Turso・libSQL・Cloudflare D1 — エッジとlocal-firstでSQLiteを使う
この章の目次開く
ここまでの章は、すべて「1台のマシンの中で完結する」ことを前提にしてきました。SQLiteはファイルを直接読み書きするライブラリなので、これは仕様上の制約です。
しかし近年、この制約を外側から補う選択肢が増えています。ファイルをオブジェクトストレージへ継続的に複製する仕組み、SQLite互換のままサーバーモードを追加した実装、SQLiteをエッジで動かすマネージドサービスなどです。
最終章では、それらの選択肢と、SQLiteを本番に採用してよいかの判断基準を整理します。
学習者結局のところ、SQLiteは本番で使っていいんでしょうか? 記事によって言っていることが違う気がします。
先生「使える/使えない」で分けるから混乱するんだ。ワークロードの性質で判断すれば、答えははっきりするよ。
そもそも何が足りないのか
複数台構成にできない理由を、あらためて分解しておきます。
| 足りないもの | 理由 | 補い方 |
|---|---|---|
| 複数マシンからのアクセス | ファイルを直接読むため、共有ストレージでは壊れる | ネットワーク越しのプロトコルを足す |
| 障害時のデータ保護 | ファイルが失われたら終わり | 別の場所へ継続的に複製する |
| 地理的に分散した読み取り | ファイルは1か所にしかない | 各地にレプリカを置く |
| 同時書き込み | 書き手は常に1つ | ほぼ解消されない(後述) |
Litestream — バックアップを継続的にする
もっとも構成が単純な選択肢です。ローカルのSQLiteはそのまま使い、WALの変更をS3互換のオブジェクトストレージへ継続的に転送します。
アプリケーションのコードは一切変わりません。SQLiteをローカルファイルとして使い続けたまま、「サーバーが消えてもデータは残る」という保証だけを足せます。
- できること — 障害からの復旧、任意時点への巻き戻し
- できないこと — 複数台からの同時利用、読み取りの分散
前章の日次バックアップでは「最大24時間分のデータを失う」リスクがありますが、Litestreamならその窓が数秒〜数分まで縮みます。
libSQL と Turso — サーバーモードと埋め込みレプリカ
libSQL は、SQLiteから派生したオープンソースの実装です。SQLiteとの互換性を保ちながら、SQLiteが持っていない機能を追加しています。
主な追加点は次の通りです。
| 機能 | 内容 |
|---|---|
| サーバーモード | HTTP / WebSocket 経由でアクセスできる |
| 埋め込みレプリカ | ローカルにファイルの複製を持ち、自動で同期する |
| 拡張された ALTER TABLE | SQLite本体より柔軟な変更ができる |
| ベクトル検索 | 拡張なしで組み込まれている |
Turso は、このlibSQLをマネージドサービスとして提供するものです。
もっとも特徴的なのが埋め込みレプリカです。アプリケーションの手元にSQLiteファイルの複製を置き、読み取りはそのローカルファイルから行い、書き込みだけをリモートの本体へ送ります。同期はバックグラウンドで行われます。
読み取りがネットワークを経由しないため、応答は通常のSQLiteと同等になります。一方で、書き込み直後にレプリカへ反映されるまでには遅延があり、書いた直後に読むと古い値が返る可能性があります。
埋め込みレプリカは結果整合です。「書き込んだ内容をすぐ読む」フローがある画面では、明示的な同期を挟むか、その部分だけプライマリから読む必要があります。
Cloudflare D1 — エッジのマネージドSQLite
Cloudflare D1 は、CloudflareのWorkers環境から使うSQLiteベースのマネージドデータベースです。2024年4月に一般提供が開始されました。
サーバーレス環境ではファイルシステムが揮発するため、第8章で触れた通り通常のSQLiteは使えません。D1はその制約を、SQLiteをサービス側に置くことで解消しています。
- Workersからバインディング経由でアクセスする
- SQL方言はSQLiteと同じものが使える
- 読み取りレプリカによって、世界各地から低遅延で読める
一方で、サービス固有の制約(1データベースあたりのサイズ上限、クエリあたりの制限など)があります。これらは変更されることがあるため、必ず公式ドキュメントで現行値を確認してください。
選択肢を比較する
| 選択肢 | アプリの変更 | 複数台からの読み取り | 書き込み | 主な用途 |
|---|---|---|---|---|
| ローカルSQLiteのみ | なし | 不可 | ローカル | CLI・テスト・デスクトップ |
| + Litestream | なし | 不可 | ローカル | 1台構成の本番。障害復旧 |
| libSQL / Turso | クライアント差し替え | 可能(レプリカ) | プライマリへ集約 | 分散した読み取りが必要なアプリ |
| Cloudflare D1 | Workers前提 | 可能 | プライマリへ集約 | エッジで動かすアプリ |
| PostgreSQLへ移行 | 大きい | 可能 | 複数同時 | 書き込みが多いサービス |
学習者書き込みが集約されるなら、結局スケールしないのでは?
書き込みのスループットが必要なら、その通りです。ただし多くのアプリケーションは、読み取りが9割以上を占めます。ブログ、ドキュメント、社内ツール、SaaSの管理画面などがこれに当たります。そうしたワークロードでは、書き込みを1か所に集約しても問題になりません。
採用の判断基準
最後に、判断のための質問を整理します。
SQLiteが向いている
- 書き込みが1秒あたり数件〜数十件に収まる
- 読み取りが圧倒的に多い
- テナントやユーザーごとにデータを分離できる
- 運用担当者を置かずに済ませたい
- データを外部に出したくない
- オフラインでも動作させたい
PostgreSQLなどを選ぶべき
- 多数のユーザーが同時に書き込む
- 複数のアプリケーションから同じDBに書き込む
- 厳密なユーザー権限管理が必要
- 単一テーブルが数百GB規模になる
- 全文検索や地理情報で高度な機能が必要

よくあるハマりどころ
レプリカに書き込めると思ってしまう
埋め込みレプリカはあくまで読み取り用の複製です。書き込みはプライマリへ送られ、そこから同期されます。この非対称さを理解しないまま設計すると、整合性の問題に悩まされます。
結果整合を考慮せずにUIを作る
フォームを送信した直後に一覧を再取得すると、まだ反映されていないことがあります。書き込み結果を画面に即時反映したい場合は、第5章の RETURNING で受け取った値をそのまま使うのが確実です。
料金・制限を古い情報のまま判断する
この分野は変化が速く、1年前の記事の数値がそのまま通用しないことがよくあります。必ず公式の料金ページと制限一覧を確認してください。
「SQLiteだから遅い」と決めつける
適したワークロードでは、ネットワークを経由しないぶん、SQLiteのほうが速いことは珍しくありません。逆に、適さないワークロードではどう設定しても限界があります。判断すべきは速度そのものではなく、書き込みの同時実行数です。
ちゃんと使うためのポイント
- どの選択肢でも、書き込みは1か所へ集約される
- 1台構成なら、まずLitestreamで障害復旧を確保できないか検討する
- libSQL / Turso の埋め込みレプリカは、読み取りをローカルに置いて速度を稼ぐ仕組み
- 埋め込みレプリカは結果整合。書いた直後に読む導線には配慮が要る
- Cloudflare D1 はサーバーレス環境からSQLiteを使うための選択肢
- 判断の軸はアクセス数ではなく「書き込みの同時実行数」と「読み書きの比率」
- 料金・制限は必ず公式ドキュメントで最新値を確認する
この本のまとめ
12章を通じて、SQLiteを次の順序で見てきました。
- サーバーを持たない仕組みと、そこから来る得意・不得意(第1章)
sqlite3コマンドによる操作(第2章)- 型の緩さと
STRICTによる防御(第3章) - rowid と制約の設計(第4章)
- SQLiteならではのSQL(第5章)
- WALモードとロックの扱い(第6章)
- インデックスと実行計画(第7章)
- Node.jsからの利用(第8章)
- FTS5による全文検索(第9章)
- ベクトル検索とローカルRAG(第10章)
- バックアップと運用(第11章)
SQLiteは、選択肢が少ないぶん判断が速いデータベースです。仕組みを理解していれば、「ここは使える」「ここは無理」を自分で見極められるようになります。
SQLの文法そのものをさらに固めたい場合は、SQLとデータベースの基礎へ戻って復習してみてください。
参考リンク
- Litestream 公式サイト
- Turso 公式サイト
- libSQL — GitHub
- Cloudflare D1 公式ドキュメント
- SQLite公式 — Appropriate Uses For SQLite