本文へスキップ
ウェブエンジニア問題集
第12章

Turso・libSQL・Cloudflare D1 — エッジとlocal-firstでSQLiteを使う

約12分
この章の目次開く

ここまでの章は、すべて「1台のマシンの中で完結する」ことを前提にしてきました。SQLiteはファイルを直接読み書きするライブラリなので、これは仕様上の制約です。

しかし近年、この制約を外側から補う選択肢が増えています。ファイルをオブジェクトストレージへ継続的に複製する仕組み、SQLite互換のままサーバーモードを追加した実装、SQLiteをエッジで動かすマネージドサービスなどです。

最終章では、それらの選択肢と、SQLiteを本番に採用してよいかの判断基準を整理します。

学習者学習者

結局のところ、SQLiteは本番で使っていいんでしょうか? 記事によって言っていることが違う気がします。

先生先生

「使える/使えない」で分けるから混乱するんだ。ワークロードの性質で判断すれば、答えははっきりするよ。

そもそも何が足りないのか

複数台構成にできない理由を、あらためて分解しておきます。

足りないもの理由補い方
複数マシンからのアクセスファイルを直接読むため、共有ストレージでは壊れるネットワーク越しのプロトコルを足す
障害時のデータ保護ファイルが失われたら終わり別の場所へ継続的に複製する
地理的に分散した読み取りファイルは1か所にしかない各地にレプリカを置く
同時書き込み書き手は常に1つほぼ解消されない(後述)
どの選択肢も、書き込みは最終的に1か所へ集約されます。「SQLiteでも複数台で書ける」という理解は、ほとんどの場合正しくありません。

Litestream — バックアップを継続的にする

もっとも構成が単純な選択肢です。ローカルのSQLiteはそのまま使い、WALの変更をS3互換のオブジェクトストレージへ継続的に転送します。

アプリケーションのコードは一切変わりません。SQLiteをローカルファイルとして使い続けたまま、「サーバーが消えてもデータは残る」という保証だけを足せます。

  • できること — 障害からの復旧、任意時点への巻き戻し
  • できないこと — 複数台からの同時利用、読み取りの分散

前章の日次バックアップでは「最大24時間分のデータを失う」リスクがありますが、Litestreamならその窓が数秒〜数分まで縮みます。

libSQL と Turso — サーバーモードと埋め込みレプリカ

libSQL は、SQLiteから派生したオープンソースの実装です。SQLiteとの互換性を保ちながら、SQLiteが持っていない機能を追加しています。

主な追加点は次の通りです。

機能内容
サーバーモードHTTP / WebSocket 経由でアクセスできる
埋め込みレプリカローカルにファイルの複製を持ち、自動で同期する
拡張された ALTER TABLESQLite本体より柔軟な変更ができる
ベクトル検索拡張なしで組み込まれている

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 D1Workers前提可能プライマリへ集約エッジで動かすアプリ
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. サーバーを持たない仕組みと、そこから来る得意・不得意(第1章)
  2. sqlite3 コマンドによる操作(第2章)
  3. 型の緩さと STRICT による防御(第3章)
  4. rowid と制約の設計(第4章)
  5. SQLiteならではのSQL(第5章)
  6. WALモードとロックの扱い(第6章)
  7. インデックスと実行計画(第7章)
  8. Node.jsからの利用(第8章)
  9. FTS5による全文検索(第9章)
  10. ベクトル検索とローカルRAG(第10章)
  11. バックアップと運用(第11章)

SQLiteは、選択肢が少ないぶん判断が速いデータベースです。仕組みを理解していれば、「ここは使える」「ここは無理」を自分で見極められるようになります。

SQLの文法そのものをさらに固めたい場合は、SQLとデータベースの基礎へ戻って復習してみてください。

参考リンク

SQLクイズに挑戦するこの本で学んだデータベースの知識を、4択クイズでアウトプットして定着させよう