Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

KV-backed Durable Object Storage(レガシー)

最終更新 Markdown で表示Agent セットアップ

Durable Object Storage API を使うと、Durable Objects はトランザクション対応で強い一貫性を持つストレージにアクセスできます。Durable Object に付属するストレージは、その一意なインスタンス専用であり、ほかのオブジェクトからはアクセスできません。

Durable Object Storage API には、SQL、ポイントインタイムリカバリ(PITR)、キーバリュー(KV)、アラーム API など、いくつかのメソッドがあります。利用できる API メソッドは、Durable Objects クラスのストレージバックエンドが SQLiteKV かによって異なります。

メソッド 1 SQLite バックエンドの Durable Object クラス KV バックエンドの Durable Object クラス
SQL API
PITR API
Synchronous KV API 2, 3
Asynchronous KV API 3
Alarms API

脚注

1 各メソッドは暗黙的にトランザクションでラップされます。複数のキーバリューペアにアクセスする場合でも、結果はアトミックであり、ほかのストレージ操作から分離されます。

2 get()put()delete()list() などの KV API メソッドは、隠し SQLite テーブル __cf_kv にデータを保存します。テーブル一覧ではこのテーブルを確認できますが、SQL API から中身へアクセスすることはできません。

3 SQLite バックエンドの Durable Objects は ctx.storage.kv を使う 同期 KV API メソッド も利用します。一方、KV バックエンドの Durable Objects が提供するのは 非同期 KV API メソッド だけです。

ストレージにアクセスする

Durable Objects は、DurableObjectStorage インターフェイス経由で Storage API にアクセスし、DurableObjectState::storage プロパティで使います。Durable Object コンストラクターに渡される ctx パラメーターを使い、this.ctx.storage として参照することが多いです。

次のコードスニペットは、Durable Object Storage API でデータを保存・取得する方法を示します。

export class Counter extends DurableObject {
	constructor(ctx, env) {
		super(ctx, env);
	}

	async increment() {
		let value = (await this.ctx.storage.get("value")) || 0;
		value += 1;
		await this.ctx.storage.put("value", value);
		return value;
	}
}
export class Counter extends DurableObject {
  constructor(ctx: DurableObjectState, env: Env) {
    super(ctx, env);
  }

  async increment(): Promise<number> {
    let value: number = (await this.ctx.storage.get("value")) || 0;
    value += 1;
    await this.ctx.storage.put("value", value);
    return value;
  }
}
from workers import DurableObject

class Counter(DurableObject):
  def __init__(self, ctx, env):
    super().__init__(ctx, env)

  async def increment(self):
    value = (await self.ctx.storage.get("value")) or 0
    value += 1
    await self.ctx.storage.put("value", value)
    return value

JavaScript はシングルスレッドで、イベント駆動のプログラミング言語です。そのため JavaScript ランタイムは、デフォルトではリクエスト同士のインターリーブを許可し、並行性のバグにつながることがあります。Durable Objects ランタイムは、input gatesoutput gates を組み合わせて、ストレージ操作時にこの種の並行性バグを避けます。詳細は ブログ記事 を参照してください。

非同期 KV API

KV バックエンド Durable Objects は、非同期の KV API メソッドを提供します。

get

  • ctx.storage.get(key string, options Object 任意): Promise<any>

    • 指定したキーに対応する値を取得します。戻り値の型は、そのキーに以前書き込まれた値と同じです。キーが存在しない場合は undefined です。
  • ctx.storage.get(keys Array<string>, options Object 任意): Promise<Map<string, any>>

    • 指定した各キーに対応する値を取得します。Map 内の各戻り値の型は、対応するキーに以前書き込まれた値と同じです。Map の結果は UTF-8 エンコーディングの昇順で並び、存在しないキーは省略されます。一度に最大 128 個のキーを指定できます。

利用できるオプション

  • allowConcurrency: boolean

    • デフォルトでは、予期しない競合状態を避けるため、ストレージ操作の実行中は Object への I/O イベントの配信を一時停止します。この動作を無効にして同時イベントの配信を許可するには、allowConcurrency: true を渡します。
  • noCache: boolean

    • true の場合、キーと値はメモリ内キャッシュに挿入されません。キーがすでにキャッシュにある場合はキャッシュされた値を返しますが、最終使用時刻は更新しません。近い将来このキーを使わない見込みのときに使います。このフラグはヒントです。コードの意味は変わりませんが、パフォーマンスに影響する場合があります。

put

  • put(key string, value any, options Object 任意): Promise

    • 値を保存し、指定したキーに関連付けます。値は structured clone algorithm がサポートする任意の型を使えます。ほとんどの型が対象です。

      キーと値のサイズ上限は、利用している Durable Object のストレージバックエンドによって異なります。次のいずれかを参照してください。

      KV バックエンドの Durable Object では、シリアライズ後の値が 128 KiB(131072 バイト)の値サイズ上限を超えると、書き込みが適用される前に put()RangeError を投げます(例: Values cannot be larger than 131072 bytes.)。

  • put(entries Object, options Object 任意): Promise

delete

  • delete(key string, options Object 任意): Promise<boolean>

    • キーと対応する値を削除します。キーが存在した場合は true、存在しなかった場合は false を返します。
  • delete(keys Array<string>, options Object 任意): Promise<number>

    • 指定したキーと対応する値を削除します。一度に最大 128 個のキーを指定できます。削除したキーと値のペアの数を返します。

利用できるオプション

  • put()delete()deleteAll() は次のオプションをサポートします。

  • allowUnconfirmed boolean

    • デフォルトでは、以前の書き込みがディスクへフラッシュされたことを確認するまで、Durable Object からの送信ネットワークメッセージを一時停止します。書き込みが失敗した場合、システムは Object をリセットし、送信中のメッセージをすべて破棄して、クライアントにはエラーを返します。

    • こうすることで、書き込みが実際に成功しない限り外部から Object の動作は観測できないため、Durable Objects は書き込みが完了する前に確定してしまう心配なく、書き込みと並行して実行を続けられます。

    • 書き込みのあと、後続のネットワークメッセージがわずかに遅れることがあります。未確認の書き込みを前提に通信しても問題ないアプリケーションもあります。ネットワークトラフィックをすぐに許可したいプログラムもあります。その場合は allowUnconfirmedtrue に設定し、デフォルトの動作を無効にします。

    • 一部の送信ネットワークメッセージだけをすぐに進めたい場合は、allowUnconfirmed オプションで進めたいメッセージのブロックを避け、別途 sync() を呼びます。sync() は、以前の書き込みがすべてディスクへ正常に永続化されたときにだけ解決する Promise を返します。

  • noCache boolean

    • true の場合、ディスクへの書き込みが完了した時点で、キーと値はメモリから破棄されます。

    • 近い将来キーを使わない場合は noCache を使います。noCache はコードの意味を変えませんが、パフォーマンスに影響する場合があります。

    • 書き込み完了前に get() でキーを取得した場合は、書き込みバッファーのコピーが返されます。これにより、最新の put() 呼び出しとの一貫性が保たれます。

list

  • list(options Object 任意): Promise<Map<string, any>>
    • 現在の Durable Object に関連付けられたすべてのキーと値を、キーの UTF-8 エンコーディングに基づく昇順で返します。

    • Map 内の各戻り値の型は、対応するキーに以前書き込まれた値と同じです。

    • オプションなしでこの list を呼ぶ前に、Durable Object にどれだけデータが保存されているかに注意してください。すべてのデータが Durable Object のメモリに読み込まれ、上限 に達する可能性があります。それが心配な場合は、以下で説明するオプションを list に渡してください。

利用できるオプション

  • start string

    • リスト結果の開始キーです。このキーを含みます。
  • startAfter string

    • リスト結果の開始位置となるキーの直後です。このキーは含みません。start と同時には使えません。
  • end string

    • リスト結果の終了キーです。このキーは含みません。
  • prefix string

    • キーがこのプレフィックスで始まるキーと値のペアだけに結果を限定します。
  • reverse boolean

    • true の場合、デフォルトの昇順ではなく降順で結果を返します。
    • reverse を有効にしても、startstartKeyendKey の意味は変わりません。start は辞書順で返せる最小のキー(含む)を定義し、降順リストでは実質的な終点になります。end は辞書順でリストが対象とする最大のキー(含まない)を定義し、降順リストでは実質的な始点になります。
  • limit number

    • 返すキーと値のペアの最大数です。
  • allowConcurrency boolean

    • 上記の get() のオプションと同じです。
  • noCache boolean

    • 上記の get() のオプションと同じです。

Alarms

getAlarm

  • getAlarm(options Object 任意): Promise<Number | null>
    • 現在のアラーム時刻(設定されている場合)を、エポックからの整数ミリ秒として取得します。アラームは、まだ開始していない場合、または失敗して再試行が始まっていない場合に、設定済みとみなされます。アラームが設定されていない場合、getAlarm()null を返します。

利用できるオプション

  • get() と同じオプションです。ただし noCache はありません。

setAlarm

  • setAlarm(scheduledTime Date | number, options Object 任意): Promise

    • 現在のアラーム時刻を設定します。JavaScript の Date、またはエポックからの整数ミリ秒を受け付けます。

    setAlarm()Date.now() 以前の時刻を渡した場合、アラームはすぐあとで非同期実行されるようスケジュールされます。このときアラームハンドラーが実行中でも、キャンセルはされません。アラームはミリ秒単位で設定でき、通常は設定時刻の数ミリ秒後に実行されます。ただしメンテナンスやフェイルオーバー中の障害により、最大 1 分遅れることがあります。

deleteAlarm

  • deleteAlarm(options Object 任意): Promise
    • アラームが存在する場合は削除します。アラームハンドラーが実行中の場合はキャンセルしません。

利用できるオプション

  • setAlarm()deleteAlarm()put() と同じオプションをサポートします。ただし noCache はありません。

その他

deleteAll

  • deleteAll(options Object 任意): Promise
    • 保存されているデータをすべて削除し、Durable Object が使っているストレージを実質的に解放します。キーバリューストレージバックエンドの Durable Object では、deleteAll() はその Durable Object のすべてのキーと対応する値を削除します。SQLite ストレージバックエンド の Durable Object では、deleteAll() はその Durable Object のプライベート SQLite データベースの内容をすべて削除します。SQL データとキーバリューデータの両方が対象です。
    • キーバリューストレージバックエンドの Durable Object では、進行中の deleteAll() が失敗し、一部のデータだけが残ることがあります。SQLite ストレージバックエンドの Durable Object では、deleteAll() はアトミック(すべて成功するか、まったく実行されないか)なので、部分削除の問題はありません。
    • 互換日付が 2026-02-24 以降の Workers では、deleteAll() は有効な アラーム も削除します。それより前の互換日付では、deleteAll() はアラームを削除しません。別途 deleteAlarm() を使うか、delete_all_deletes_alarm 互換フラグ を有効にしてください。

transactionSync

  • transactionSync(callback): any
    • SQLite バックエンドの Durable Object でのみ利用できます。

    • callback() をトランザクションで包んで実行し、その結果を返します。

    • callback() が例外を投げた場合、トランザクションはロールバックされます。

    • コールバックは同期的に完了する必要があります。つまり、async として宣言したり、Promise を返したりしてはいけません。トランザクションに含められるのは同期的なストレージ操作だけです。これは、同期的に完了する ctx.storage.sql.exec() を使った SQL クエリ向けです。

transaction

  • transaction(closureFunction(txn)): Promise

    • txn に対して呼ばれた一連のストレージ操作を、1 つのトランザクションとして実行します。コミットに成功するか、中止されます。

    • 明示的なトランザクションは、もはや必要ありません。間に await を挟まない一連の書き込み操作は、自動的にアトミックに送信されます。また、読み取り操作を await している間は、システムが同時イベントの実行を防ぎます(allowConcurrency: true を使っている場合を除く)。そのため、一連の読み取りのあとに一連の書き込み(間にほかの I/O がない場合)は自動的にアトミックになり、トランザクションのように振る舞います。

  • txn

    • 上記で説明した put()get()delete()list() メソッドに、現在のトランザクションコンテキストでアクセスできます。トランザクションクロージャ内でトランザクションの振る舞いを得るには、トップレベルの ctx.storage オブジェクトではなく、txn オブジェクトのメソッドを呼ぶ必要があります。

      また、トランザクション中の変更をコミットせずにロールバックする rollback() 関数も使えます。rollback() を呼んだあと、txn オブジェクトへの以降の操作は例外で失敗します。rollback() はパラメーターを取らず、呼び出し元に何も返しません。

    • SQLite バックエンドのストレージエンジン を使う場合、txn オブジェクトは不要です。ctx.storage オブジェクトに対して直接行うストレージ操作(ctx.storage.sql.exec() を使った SQL クエリを含む)は、トランザクションの一部と見なされます。

sync

  • sync(): Promise
    • 保留中の書き込みをディスクへ同期します。

    • 自動的な書き込み合体(write coalescing)の通常の振る舞いと似ています。書き込みバッファーに保留中の書き込みがある場合(allowUnconfirmed オプション で送信したものも含む)、返される Promise はそれらが完了したときに解決します。保留中の書き込みがない場合、返される Promise はすでに解決済みです。

関連リソース

役に立ちましたか?