Cloudflare Durable Objectsとは何か——「ステートレス」の壁を越えるサーバーレスの新形態
Cloudflare Durable Objectsは、コンピュートとストレージを一体化した特殊なWorkerだ。チャット・マルチプレイヤーゲーム・リアルタイム協調編集など、サーバーレスが苦手としてきた「状態管理」を、インフラ不要で実現する仕組みを解説する。
- Cloudflare
- Durable Objects
- Workers
- サーバーレス
- WebSocket
- SQLite
サーバーレスの弱点として長らく語られてきたのが「ステート(状態)を持てない」という問題だ。Cloudflare Workersはリクエストのたびにコールドスタートし、処理が終われば消え去る。これはスケーラビリティの観点では美しい設計だが、複数のクライアントが同じ状態を共有するアプリケーション——チャット、マルチプレイヤーゲーム、共同編集ツールなど——には相性が悪い。
それを解決するために生まれたのが Cloudflare Durable Objects だ。
Durable Objectsとは
Durable Objectsは「コンピュートとストレージを唯一無二の形で組み合わせた、特殊なWorker」である。
通常のWorkerとの最大の違いは2点ある。
まず、グローバルに一意な名前(ID)を持つことだ。世界中のどこからリクエストを送っても、同じ名前のDurable Objectには同じインスタンスが応答する。これによって、複数のクライアント間で「誰かが調整役になる必要がある場面」を、自然に実装できる。
次に、永続ストレージを持つことだ。このストレージはオブジェクトと同じ場所に存在し、強い一貫性(Strong Consistency)を持ちながらも高速にアクセスできる。データはリクエストをまたいで保持され、オブジェクトがアイドル状態になってもストレージの内容は消えない。
通常のWorkerと同じくJavaScript / TypeScript(およびWASM)で書け、自動プロビジョニング・自動スケーリングも変わらない。インフラを自前で管理する必要はない。
アーキテクチャの核心:「アトム」という設計思想
Durable Objectsを使うとき、最も重要な設計上の問いは「1つのオブジェクトが何を表すか」だ。
公式が推奨する考え方は、協調が必要な論理単位ごとに1つのオブジェクトを作ることだ。チャットルームなら1ルーム=1オブジェクト。ゲームセッションなら1セッション=1オブジェクト。ドキュメント共同編集なら1ドキュメント=1オブジェクト。
この単位を「アトム(原子)」と呼ぶ。共有データベースとロックという従来のアプローチの代わりに、アプリケーションの各「アトム」が、プライベートなストレージを持つシングルスレッドの実行環境を得る。
逆にやってはいけないのが、「グローバルなシングルトン」として1つのDurable Objectにすべてのリクエストを集中させることだ。単一オブジェクトの処理能力は1秒あたり概ね500〜1,000リクエスト程度が上限であり、これを超えると過負荷エラーが返る。並列性を活かすには、適切な粒度で多数のオブジェクトに分散させるのが正しいアプローチだ。
シングルスレッドと強整合性
各Durable Objectはシングルスレッドで動作し、リクエストを順番に処理する。ブラウザのJavaScriptと同じ協調型マルチタスクだ。これはパフォーマンス上の制約に聞こえるかもしれないが、実は大きなメリットがある。
競合状態(Race Condition)を気にしなくていい。データベースのロックを実装する必要がない。複数クライアントが同時に書き込もうとしても、Durable Objectsのランタイムがリクエストをシリアライズしてくれる。
Cloudflareはこの性質を「Easy, Fast, Correct — Choose three」と表現している。分散システムでは通常「3つのうち2つしか選べない」とされるトレードオフを、設計で解消したという主張だ。
ストレージ:SQLiteが標準に
Durable ObjectsのストレージバックエンドにはかつてKey-Valueのみが存在したが、2024年9月にSQLiteバックエンドがベータ公開され、現在は**正式にGA(一般提供)**となっている。新しいDurable Objectクラスにはこちらを使うことが公式に推奨されている。
各オブジェクトはプライベートな組み込みSQLiteデータベースを持ち、sql.exec()によるSQLクエリが使える。ストレージはコンピュートと同一スレッドで動くため、実質的にゼロレイテンシーでアクセスできる。これは外部データベースへのラウンドトリップが発生するD1とは根本的に異なる点だ。
SQLiteバックエンドの主なスペック:
- 容量上限:Paidプランで1オブジェクトあたり最大10GB、アカウント全体では制限なし
- Point-in-Time Recovery:過去30日間の任意の時点にデータを復元可能
- Data Studio:CloudflareダッシュボードからUIでデータを閲覧・編集できる
なお、旧来のKey-Valueバックエンドは現在もPaidプランでのみ利用可能だが、新規プロジェクトでの採用は推奨されていない。
WebSocket Hibernation
リアルタイム通信において、Durable ObjectsはWebSocketサーバーとして機能できる。すべてのWebSocket接続を1つのオブジェクトで管理することで、クライアント間のリアルタイムな状態共有が非常にシンプルに実装できる。
ただし、WebSocket接続を保ちながらDurable Objectがメモリ上で生き続けると、アイドル時間にも課金が発生する。これを解決するのがWebSocket Hibernation APIだ。
このAPIを使うと、WebSocket接続を維持しつつDurable Objectをスリープ(ハイバネーション)させられる。たとえばチャットアプリで誰もメッセージを送っていない30分間は、Durable Objectはハイバネーション状態となり課金は止まる。次のメッセージが届いた瞬間に再起動し、処理を行う。コスト効率とリアルタイム性を両立する重要な機能だ。
Alarms API
Durable ObjectsにはAlarms APIも組み込まれている。将来の特定時刻にオブジェクトを起動し、処理を実行するスケジューリング機能だ。setAlarm()で予約し、alarm()ハンドラで実行内容を定義する。
バッチ処理・定期的なAPIポーリング・セッションタイムアウト処理など、「ある時刻に特定のオブジェクトを起こして何かさせたい」ユースケースをサーバーレスの文脈でスマートに実装できる。
ライフサイクル:スリープと復帰
Durable Objectは最初のリクエストを受けてコンストラクタが呼ばれ、メモリ上でアクティブになる。リクエスト処理が終わるとアイドル状態となり、条件を満たせばハイバネーション状態に移行する。ハイバネーション移行後10秒間新しいリクエストがなければ、ランタイムはオブジェクトをメモリから解放する。
ハイバネーション中にリクエストが届くと、再びコンストラクタが実行されてオブジェクトが復元される。メモリ上のデータはリセットされるが、ストレージの内容は永続する。したがって、次回の起動時に必要なデータは必ずストレージに書き込んでおく必要がある。
料金とFreeプランでの利用
2025年4月のアップデートで、SQLiteバックエンドのDurable ObjectsがWorkers Freeプランでも利用可能になった。Freeプランでの制限は以下の通りだ:
- リクエスト:1日10万回
- 計算時間(GB-s):1日13,000 GB-s
- ストレージ:アカウント全体で5GBまで(1オブジェクトあたり最大1GB)
Workers Paidプラン(月$5〜)ではこれらの上限が大幅に拡大され、Key-Valueバックエンドも利用できる。SQLiteストレージへの課金は2026年1月7日より開始されており、Paidプランユーザーは注意が必要だ。
D1やWorkers KVとの違い
Cloudflareのストレージ製品の中でDurable Objectsをどう位置づけるかを整理しよう。
Workers KV はグローバルに分散したKey-Valueストアで、最終的一貫性を持つ。読み取りが多く、書き込みが少ないワークロードに向いている。
D1 はサーバーレスのSQLデータベースで、複数のWorkerから共有して使う中央集権的なDBだ。コンピュートとストレージは同居しないため、Durable Objectsと比べて若干のレイテンシーが発生する。
Durable Objects はコンピュートとストレージを同一スレッドに配置し、強整合性とゼロレイテンシーアクセスを実現する。複数クライアントの協調が必要なリアルタイム・ステートフルなアプリケーションに適している。
用途が「頻繁に変化する共有状態をリアルタイムに同期する」なら、Durable Objectsが最適な選択肢になる。
実際のユースケース
Durable Objectsが威力を発揮する代表的なシナリオはこうだ:
チャットアプリでは、1チャットルーム=1オブジェクトとする。すべてのメッセージ送受信・ユーザーのプレゼンス管理・ルームの状態をそのオブジェクトが一手に担う。Redisクラスターもメッセージキューもなしにグローバルなリアルタイム同期が実現する。
ホワイトボードや共同ドキュメント編集では、1ドキュメント=1オブジェクトとし、複数ユーザーの編集操作を競合なく直列処理する。FigmaやGoogle Docsのようなアーキテクチャを、分散システムの専門知識なしに構築できる。
マルチプレイヤーゲームでは、1ゲームセッション=1オブジェクトとして、プレイヤーの状態・ゲームロジック・リアルタイム更新をユーザーに近い場所で処理する。各ゲームルームが独立してスケールするため、インフラのオーバーヘッドがない。
AIエージェントの文脈では、エージェントにメモリを持たせ、タスクを調整し、リアルタイムに意思決定させる基盤としても注目されている。Cloudflareは@cloudflare/actorsというライブラリでDurable Objectsをエージェントの基盤として抽象化する動きを進めている。
まとめ
Durable Objectsは「サーバーレスはステートを持てない」という常識を書き換えた。特にWebSocketを使ったリアルタイムアプリの構築において、RedisやメッセージキューといったミドルウェアをまるごとWorkers上のコードに置き換えられる可能性は大きい。
SQLiteバックエンドのGA化とFreeプランへの開放によって、プロトタイプから本番環境まで一貫して使えるプラットフォームとしての整備も進んだ。Astroや他のフレームワークとCloudflare Workersを組み合わせて開発している人にとって、Durable Objectsはツールボックスに加える価値のある一枚のカードだ。
「ステートが必要になった瞬間にアーキテクチャが複雑になる」という問題を、Cloudflareはシングルスレッドのオブジェクトという極めてシンプルな抽象化で解決した。その設計の清潔さに、ひとつの美学を感じる。
Last updated