Durable Objectsとは?状態を持つWorkers

《 Cloudflare完全ガイド 目次へ 》

第5章の前半では、Workers・Pages・Email Routingという「サーバーを持たずに動かす」仕組みを見てきました。ここからは、その土台であるWorkersの弱点を補う仕組みに入ります。

Workersの解説で、「Workerは状態を保持できない」と述べました。リクエストごとに独立して動き、変数に入れた値は次のアクセスまで残りません。この性質は、拡張性の高さと引き換えに生まれたものです。しかし現実には、状態を持たなければ書けない機能があります。チャットルーム、共同編集、オンラインゲーム、在庫の取り合い。こうした「複数の人が同じものを同時に触る」処理です。

Durable Objects(デュラブルオブジェクト:durable=永続的な)は、この問題を正面から解決するために作られた、状態を持てるWorkersです。

このページで分かること

  • Workersが状態を持てない理由と、それが困る場面
  • Durable Objectが「名前で一意に決まるインスタンス」であるとはどういうことか
  • 処理が順番に実行されることで、なぜ競合が起きないのか
  • 内蔵ストレージ(SQLiteベース)とWebSocketの扱い
  • 料金と主な制限、KVやD1との使い分けの入口

なぜWorkersだけでは足りないのか

例として、オンラインの会議室予約を考えます。残り1席の枠に、2人が同時に「予約」を押したとします。

通常のWorkersでは、この2つのリクエストは世界の別々の拠点で、同時に、互いを知らないまま実行されます。両方が「残り1席ある」と読み取り、両方が「予約完了」と応答してしまう。これが競合状態(レースコンディション)です。

同じことは、チャットルームの参加者一覧、ゲームの盤面、共同編集中の文書でも起こります。「いま誰がどういう状態なのか」を一箇所で管理し、変更を順番に処理する担当者が必要です。

一般的なWebアプリケーションでは、この担当者をデータベースが務めます。しかしデータベースは特定の場所にあるため、世界中で動くWorkersからは遠く、しかもアクセスが集中すると詰まります。Cloudflareが出した答えは、「担当者そのものをエッジに置く」というものでした。

Durable Objectとは:名前で決まるひとつの実体

Durable Objectは、グローバルに一意な名前を持つ小さなインスタンスです。ここがすべての出発点になります。

たとえば会議室ごとに room-123 room-456 という名前を付けると、room-123 というDurable Objectは世界中でただ1つだけ存在します。日本からのアクセスも、ドイツからのアクセスも、room-123 を指定すれば必ず同じ実体にたどり着きます。

Durable Objectに処理が集まる仕組み
図1:Durable Objectに処理が集まる仕組み

この性質から、次の2つが保証されます。

1つ目は、状態を持てることです。 インスタンスがメモリ上に持つ値は、次のリクエストでもそのまま残っています。加えて、そのオブジェクト専用の内蔵ストレージを持ち、電源が落ちても消えないデータを置けます。

2つ目は、処理が順番に実行されることです。 ひとつのDurable Objectは同時に複数の処理を走らせません。先ほどの予約の例なら、2人のリクエストは必ず前後して処理され、後の人には「満席です」と返ります。ロックや排他制御を自分で書かなくても、構造として競合が起きないわけです。

Workersが「どこでも動く代わりに何も覚えていない」のに対し、Durable Objectは「1箇所にしかない代わりに全部覚えている」存在です。両者を組み合わせ、通常の処理はWorkersで捌き、調整が必要な部分だけDurable Objectへ集める、というのが基本的な設計になります。

内蔵ストレージ

各Durable Objectは、自分専用のストレージを持ちます。現在はSQLite(軽量なデータベース)を土台にした方式が標準で、SQLで読み書きできます。

このストレージの特徴は、オブジェクトと同じ場所に置かれることです。つまりデータへのアクセスは、ネットワークをまたがない手元の読み書きになります。トランザクションに対応し、強い一貫性(書いた直後に読めば必ずその値が返る)が保証されます。

第6章で扱うKVが「世界中に配って読みを速くする代わりに、反映に少し時間がかかる」設計なのに対し、Durable Objectのストレージは「1箇所に集める代わりに、常に正しい値が読める」設計です。この違いが、使い分けの分かれ目になります。

WebSocketとの相性

リアルタイムな通信を扱うWebSocket(ブラウザとサーバーが接続を張りっぱなしにして双方向にやり取りする仕組み)とも、Durable Objectは相性が良いです。

チャットルームの参加者全員のWebSocket接続を、ひとつのDurable Objectが束ねて管理できます。誰かが発言したら、その場から全員へ配れば済みます。

さらにWebSocketハイバネーションという仕組みがあり、接続は保ったまま、やり取りがない間はオブジェクトをメモリから退避させられます。誰も発言していない時間の課金を抑えつつ、多数の接続を維持できます。

何に使えるのか

  • チャット・通知:ルーム単位でDurable Objectを作り、参加者と履歴を管理する
  • 共同編集:文書ごとにオブジェクトを作り、編集の順序を確定させる
  • オンラインゲーム:対戦部屋ごとに盤面を持たせる
  • 在庫・座席・予約:同時アクセスによる二重確保を構造的に防ぐ
  • レート制限やカウンター:利用者ごと・APIキーごとに正確な回数を数える
  • AIエージェント:会話の文脈や進行中のタスクを保持する(第7章のAgentsもこの上に構築されています)

共通するのは、「特定の単位(部屋・文書・ユーザー)ごとに、状態と順序が必要な処理」という点です。

料金と主な制限

かつては有料プラン専用でしたが、現在はSQLiteベースのDurable Objectsが無料プランでも使えます(2026年8月時点)。

Free Workers Paid
リクエスト 1日10万まで 月100万まで込み、超過は100万あたり0.15ドル
実行時間 1日13,000 GB秒まで 月400,000 GB秒まで込み、超過は100万GB秒あたり12.50ドル
保存データ アカウント合計5GBまで 5GB込み、超過は1GBあたり月0.20ドル
行の読み取り 1日500万行まで 月250億行込み
行の書き込み 1日10万行まで 月5,000万行込み

主な制限は次のとおりです。

  • 1オブジェクトあたりの保存容量:10GB
  • リクエスト:1オブジェクトあたり毎秒1,000件程度が目安(ソフトリミット)
  • CPU時間:既定30秒、最大5分(Workersと同じ)
  • クラス数:Free 100/Paid 500

料金表の「実行時間(GB秒)」は、オブジェクトがメモリ上に存在していた時間に対する課金です。リクエストの回数だけでなく、起きている時間にも費用が掛かる点がWorkersとの違いです。前述のハイバネーションが重要になるのはこのためです。

初心者が注意するポイント

  • 1つのオブジェクトに集中させすぎない:Durable Objectは処理を順番に実行するため、そこがボトルネックになります。全ユーザーで1つのオブジェクトを共有するような設計は避け、部屋ごと・ユーザーごとのように細かく分けてください
  • 置かれる場所は自動で決まります:オブジェクトは最初にアクセスされた地域の近くに作られ、そこに留まります。世界中から使う場合、遠い利用者は相対的に遅くなります。必要なら作成時に地域のヒントを指定できます
  • データは消さないかぎり課金され続けます:使い終わった部屋のオブジェクトを放置すると、保存データの分の費用が残ります。不要になったら明示的に削除してください
  • まずKVやD1で足りないか考える:状態や順序が本当に必要なのかを見極めてください。読み取り中心の設定値ならKV、普通のデータベース用途ならD1のほうが適しています。使い分けは第6章で改めて整理します
  • 無料プランではSQLiteベースのみです:古い記事にあるKey-Value方式のDurable Objectsは有料プラン向けです。これから作るならSQLiteベースを選んでください

関連サービス

  • Workers:Durable Objectを呼び出す側。通常の処理はこちらで捌く(第5章)
  • D1:アプリ全体で共有するデータベース。用途が異なる(第6章)
  • Workers KV:読み取り中心で、一貫性より速度を優先する場合の選択肢(第6章)
  • Queues / Workflows:順番に処理したい非同期の仕事を扱う仕組み(次ページ)
  • Agents:Durable Objectsを土台にしたAIエージェントの仕組み(第7章)

まとめ

  • Workersは状態を持てないため、複数の利用者が同じものを同時に触る処理は書けない
  • Durable Objectは、グローバルに一意な名前で決まる、世界にひとつだけのインスタンス
  • 同じ名前を指定すれば、どこからアクセスしても必ず同じ実体に届く
  • 処理が順番に実行されるため、競合状態が構造的に起きない
  • SQLiteベースの内蔵ストレージを持ち、強い一貫性のある読み書きができる
  • WebSocketを束ねる用途に向き、ハイバネーションで待機中の費用を抑えられる
  • 現在は無料プランでも利用可能。ただし1つのオブジェクトに集中させない設計が前提

次のページでは、同じく処理の順序と確実性に関わる仕組みとして、QueuesとWorkflowsを扱います。「すぐに返さなくてよい仕事」を安全に後回しにする方法です。

次に読む

→ ガイドの目次に戻る

※本記事の情報は 2026年8月時点のものです。

タイトルとURLをコピーしました