ブログに戻る

Cloudflare Workers KV Instant:1.62msのゲーム設定読み取りを実現するランクブック

公開日 2026年10月2日
Cloudflare Workers KV Instant:1.62msのゲーム設定読み取りを実現するランクブック AIを活用して生成

要点まとめ

解説:Cloudflare Workers KV Instantの新モードで1.62msのp99読み取りと256msの書き込みレプリケーションを実現。ゲーム設定の古さを検出する障害モード、エッジ配信の実装手順、ハードリミット、マネージド設定サービスとの比較まで詳しく解説していきます。

ライブオプスチームが重要な設定更新をプッシュするとき——エコノミー悪用の修正、緊急イベントスケジュールの変更、メンテナンスウィンドウのフラグ——地球の反対側にいるプレイヤーが4.38秒もの間、古いデータを読み続けるべきではありません。これは従来のCloudflare Workers KVにおけるp99書き込みレプリケーション時間です。静的マーケティングページなら誰も気にしません。しかし、リアルマネーや競技の整合性がかかっているライブゲームでは、この伝播ギャップは重大なリスクです。

Cloudflareは先頃、Workers KV Instantを発表しました。これは内部のQuicksilver v2ストアを搭載したWorkers KVの新モードです。同じおなじみのget()、put()、list()、delete() APIを提供します。内部のエンジンは完全に異なります——Cloudflareのグローバルネットワーク上のすべてのリクエストの設定参照を処理しているのと同じエンジンです。その結果、1.62msのp99読み取りと256msのp99書き込みレプリケーションを300以上のエッジロケーションで実現します。

このランクブックでは、実際に何が変わったのか、ゲームが古い設定の障害モードに陥っているかを検出する方法、エッジホスト型ゲーム設定のステップバイステップ実装、KV Instantが一部のワークロードに適さないハードリミット、そしてマネージドリモート設定サービスが自前構築よりも理にかなうケースについて解説します。


実際に変わったこと: KV Instant vs KV Classic

Workers KV Classicは結果整合性を採用しています。キーを書き込むと、Cloudflareが非同期にエッジロケーションへレプリケーションします。その間、読み取りは古い値を取得する可能性があります。整合性モデルは「TTLベースのキャッシュ無効化を伴う最終書き込み勝ち」です。これは静的アセットやユーザー設定——書き込み頻度が低く、数秒の古さを許容できるデータ——に適しています。

KV InstantはQuicksilver v2を使用します。これはCloudflareが自社の設定配布用に構築した内部ストアです。CloudflareのすべてのリクエストはすでにQuicksilverに触れています——ルーティングルール、ファイアウォール設定、レート制限しきい値などです。これはほとんどのゲームバックエンドが到達しないスケールで実戦テスト済みです。

具体的なパフォーマンス比較は以下の通りです:

メトリック KV Instant KV Classic
p99読み取り(全) 1.62ms 287ms
p99書き込みレプリケーション 256ms 4,380ms
中央値書き込みレプリケーション 107ms < 1秒(サブ秒精度なし)

これは177倍の読み取りレイテンシ改善と17倍の書き込みレプリケーション改善です。これらの数値はCloudflareが全300以上のエッジロケーションで実施したベンチマークに基づいています。

ゲームバックエンドにとっての意味は直接的です: すべてのプレイヤーリクエスト——ログイン時、マッチ開始時、インベントリ取得時、ショップオープン時——で設定を読み取ることができ、読み取りコストはp99でも2ms未満です。待つべきTTLはありません。プレイヤーAが悪用修正を確認できてプレイヤーBができないというキャッシュ整合性ウィンドウもありません。


ランクブック: ゲーム内の古い設定障害を検出する

移行する前に、この問題があるかどうかを把握する必要があります。障害モード、検出方法、そしてそのコストを見ていきましょう。

障害モード1: TTL期限切れによる古い読み取り

何が壊れるか: 設定ストアがTTLベースのキャッシュを使用しています。フィーチャーフラグが更新されたが、東京のプレイヤーはエッジキャッシュが期限切れになるまで30〜60秒間古い値を読み続けます。

検出方法:

  • 設定が最後に更新された書き込みタイムスタンプとともに、各クライアントに返された設定バージョンハッシュをログに記録します。
  • 書き込みから2秒以上経過した古い設定バージョンを受け取っているクライアントをクエリします。
  • ダッシュボードを構築: count of (stale_reads) / count (total_reads)。設定プッシュ中に0%を超えるものはすべて古い読み取りウィンドウです。

クイック診断クエリパターン(ロギングスタックに合わせて調整):

SELECT
  received_config_version,
  expected_config_version,
  COUNT(*) AS stale_count,
  MAX(received_at - config_updated_at) AS max_staleness
FROM config_read_log
WHERE config_updated_at > NOW() - INTERVAL '1 hour'
  AND received_config_version != expected_config_version
GROUP BY received_config_version, expected_config_version
ORDER BY max_staleness DESC;

コスト: 古いウィンドウ内のプレイヤーは異なるゲーム状態を経験します。競技ゲームでは、一方のプレイヤーは悪用が修正されたのを見て、もう一方は見ません。イベント駆動型ゲームでは、一部のプレイヤーが期間限定ウィンドウを完全に逃します。これは信頼の問題です。

障害モード2: ホットパスでの設定読み取りによるレイテンシスパイク

何が壊れるか: 設定ストアの読み取りレイテンシが十分に高い(100〜300ms)ため、すべてのリクエストで読み取る余裕がありません。代わりにクライアント側または高速だが古くなり得るローカルキャッシュにキャッシュします。キャッシュは99%の確率で正しいですが、間違っているときは非常に間違っています。

検出方法:

  • 設定読み取りコールのp50、p95、p99レイテンシを測定します。p99が50msを超える場合、リクエストごとのチェックには遅すぎます。
  • キャッシュヒット率を追跡します。ストアへのアクセスを避けるためにクライアント側で設定をキャッシュしている場合、すでに古さをトレードオフとして受け入れています。
  • プッシュ後に不正な設定値が残るインシデントを監視し、クライアントごとのキャッシュTTLまで追跡します。

コスト: 古さの問題を導入するレイテンシ問題を回避するために設計しています。1つの価格で2つの問題です。

障害モード3: インシデント圧力下での書き込み増幅

何が壊れるか: 緊急設定更新——機能の無効化、メンテナンスモードの有効化、壊れたエコノミーのフラグ——をプッシュする必要があり、書き込みが遅いかレート制限されています。従来のWorkers KVはキーごとに毎秒1回の書き込みを許可し、レプリケーションには数秒かかります。

検出方法:

  • インシデント対応中の書き込みから可視化までのレイテンシを追跡します。オプスチームが「設定は数秒で伝播するはず」と期待していて10秒以上かかる場合、設定ストアがインシデントのボトルネックです。
  • 緊急度の高いプッシュ中の書き込み失敗と429レート制限レスポンスを監視します。

これら3つの障害モードすべてに該当する場合、KV Instantの評価価値があります。


ゲーム設定のためのKV Instant実装: ステップバイステップ

KV Instantは現在プライベートベータです。Cloudflareのベータフォームから申し込めます。APIが従来のWorkers KVと同一であるため、実装は簡単です——ネームスペース作成のみが異なります。

ステップ1: KV Instantネームスペースを作成する

ネームスペース作成時にmode: "instant"属性を渡します:

wrangler kv namespace create "GAME_CONFIG" --mode instant

これによりネームスペースバインディングが生成されます。wrangler.tomlを更新します:

[[kv_namespaces]]
binding = "GAME_CONFIG"
id = "&lt;your-namespace-id>"

ステップ2: ゲーム設定を書き込む

KV Instantネームスペースは10,000キーバリューペアに制限され、ネームスペース全体のサイズは1MBです。各キーは最大300バイトです。これは意図的に小さいサイズです。プレイヤーデータではなく、設定フラグと設定用に設計されています。

ゲームの設定レイヤーに合わせてキーを構造化します:

// In a Cloudflare Worker that manages config
async function updateGameConfig(env) {
  const config = {
    maintenanceMode: false,
    maintenanceMessage: "Servers are updating. Back in 5 min.",
    eventSchedule: {
      currentEvent: "summer_showdown_2025",
      startTime: "2025-07-15T18:00:00Z",
      endTime: "2025-07-22T18:00:00Z",
    },
    economyTuning: {
      xpMultiplier: 1.5,
      goldDropRate: 0.85,
      shopRefreshHours: 6,
    },
    featureFlags: {
      newMatchmaking: true,
      rankedModeV2: false,
      socialLobby: true,
    },
    buildVersion: {
      minimumClient: "1.4.2",
      forceUpdate: false,
    },
  };

  await env.GAME_CONFIG.put("active_config", JSON.stringify(config));
  // Propagates to 300+ edge locations in ~256ms at p99
}

書き込み頻度制限: ネームスペースごとに毎秒1回の書き込み。これは設計上の制約であり、バグではありません——更新順序を決定論的にします。1時間に数回(またはインシデントごとに)変更される設定にとって、これはボトルネックではありません。

ステップ3: エッジから設定を配信する

すべてのリクエストで設定を読み取り、ゲームクライアントに配信するCloudflare Workerを構築します:

export default {
  async fetch(request, env, ctx) {
    // Every player request reads fresh config — 1.62ms p99
    const raw = await env.GAME_CONFIG.get("active_config");
    if (!raw) {
      return new Response(JSON.stringify({ error: "config_missing" }), {
        status: 503,
        headers: { "Content-Type": "application/json" },
      });
    }

    const config = JSON.parse(raw);

    // Conditional logic at the edge — maintenance mode check
    if (config.maintenanceMode) {
      return new Response(
        JSON.stringify({
          status: "maintenance",
          message: config.maintenanceMessage,
        }),
        {
          status: 503,
          headers: { "Content-Type": "application/json" },
        }
      );
    }

    // Return relevant config slice for the client
    const clientConfig = {
      event: config.eventSchedule,
      economy: config.economyTuning,
      features: config.featureFlags,
      build: config.buildVersion,
    };

    return new Response(JSON.stringify(clientConfig), {
      headers: {
        "Content-Type": "application/json",
        "Cache-Control": "public, max-age=5", // Short cache for freshness
      },
    });
  },
};

ステップ4: ゲームクライアントで設定を消費する

クライアント側では、初期化中またはセッション開始時に設定をフェッチします。GodotゲームのGDScriptの例:

extends Node

var config_url: String = "https://config.yourgame.com/api/config"
var current_config: Dictionary = {}

func _ready():
    fetch_config()

func fetch_config():
    var http = HTTPRequest.new()
    add_child(http)
    http.request_completed.connect(_on_config_received)
    http.request(config_url)

func _on_config_received(result: int, response_code: int, headers: PackedStringArray, body: PackedByteArray):
    if response_code != 200:
        push_warning("Config fetch failed: %d" % response_code)
        return

    var json = JSON.new()
    var parse_result = json.parse(body.get_string_from_utf8())
    if parse_result != OK:
        push_warning("Config parse error")
        return

    current_config = json.data
    _apply_config(current_config)

func _apply_config(config: Dictionary):
    # Apply feature flags
    if config.has("features"):
        if config["features"].get("rankedModeV2", false):
            enable_ranked_mode()
        if config["features"].get("newMatchmaking", false):
            enable_new_matchmaking()

    # Check build version
    if config.has("build"):
        var min_version = config["build"].get("minimumClient", "0.0.0")
        if version_compare(get_app_version(), min_version) &lt; 0 and config["build"].get("forceUpdate", false):
            show_force_update_screen()

    # Apply economy tuning
    if config.has("economy"):
        EconomyManager.set_xp_multiplier(config["economy"].get("xpMultiplier", 1.0))
        EconomyManager.set_gold_drop_rate(config["economy"].get("goldDropRate", 1.0))

    print("Config applied successfully — all players now on same state")

読み取りが2ms未満でTTLの古さがないため、セッション開始時、マッチキューエントリ時、または重要なクライアントアクションのたびにfetch_config()を呼び出しても、レイテンシオーバーヘッドやキャッシュ整合性を心配する必要はありません。


KV Instantができないこと(ハードリミット)

KV Instantはそのニッチにおいて強力ですが、制約は現実的です。実装をコミットする前にこれらを評価してください:

1MBのネームスペース全体サイズ。 プレイヤーデータ、リーダーボードスナップショット、インベントリ、またはプレイヤー数に応じて増加するものを保存できません。これはグローバルに適用される設定とフラグ専用です。

最大10,000キーバリューペア。 数百のフィーチャーフラグと設定オブジェクトには十分です。プレイヤーごとのものには不十分です。

ネームスペースごとに毎秒1回の書き込み。 サブ秒の書き込み頻度が必要な場合、これはあなたのストアではありません。1時間ごとまたはインシデント中に更新されるゲーム設定には問題ありません。リアルタイムのゲーム状態同期には、別のものを探してください。

メタデータサポートなし。 getWithMetadataはnullを返します。キーにカスタムメタデータを添付できません。バージョニングやタグ付けにメタデータ依存している場合、値をそれ自体に埋め込む必要があります。

listのページネーションなし。 すべてのlistコールはネームスペース内のすべての一致するキーを返します。10,000キーの場合、これは大きなレスポンスです。キー命名とプレフィックスを意図的に設計して、リストコールのスコープを絞ってください。

コストの非対称性。 ストレージは$100/MB/月(Classicの$0.50/GB/月と比較)。クラスA書き込み操作はそれぞれ$0.10(Classicの100万件あたり$5.00と比較)。これらの数値は高書き込みワークロードには法外です。しかし読み取りは100万件あたり$0.20——Classicより60%安い。価格モデルは「まれに書き込み、常に読み取り」に強く傾いており、これはまさにゲーム設定のパターンです。


KV Instantでのゲーム設定のベストプラクティス

  1. キーに意図を持ってネームスペースを付ける。 フィーチャーフラグにはff_、エコノミーチューニングにはecon_、イベントスケジュールにはevt_のようなプレフィックスを使用します。これによりlistコールがスキャン可能になり、ネームスペース全体を読み取らずに特定のカテゴリを操作する設定管理UIを構築できます。

  2. 値にバージョンハッシュを埋め込む。 メタデータがサポートされていないため、各設定値にconfigVersionフィールドを含めます。クライアントはこのバージョンをログと分析で報告でき、リアルタイムの伝播検証ダッシュボードを提供します。

  3. 設定と状態を分離する。 KV Instantは設定——ルール、フラグ、チューニングノブ、スケジュール——を保存します。状態——プレイヤーインベントリ、マッチ結果、リーダーボードランキング——は保存しません。これらを別々のストレージバックエンドを持つ2つの異なるシステムとして設計します。「設定」ネームスペースが毎週数KB以上増加している場合、そのデータは別の場所に置いてください。

  4. 503ケースを処理する。 GAME_CONFIG.get()がnullを返す場合、ワーカーはグレースフルに失敗する必要があります。メンテナンスモードまたはキルスイッチを返します。設定キーの欠落はゲームクライアントをクラッシュさせてはいけません。クライアントではなくエッジワーカーにフォールバックを組み込みます。

  5. 圧力下での書き込み順序をテストする。 ネームスペースごとに毎秒1回の書き込みは、並行書き込みが直列化されることを意味します。2人のエンジニアが同じ秒内に設定変更をプッシュした場合、最後の書き込みが勝ちます。並行書き込みに依存するのではなく、明示的な順序を持つ設定変更キューを構築します。


マネージド設定サービスを使うべき場合

KV Instantで設定配布パイプラインを構築することは、チームにエッジワーカー、設定管理UI、バージョニングスキーム、クライアント側フェッチロジック、およびその周辺のインシデント対応手順を所有する帯域がある場合、堅実なエンジニアリング上の決定です。これは実際のインフラストラクチャ作業です——個々には難しくありませんが、出荷タイムライン全体に積み上がります。

配管を運用せずに設定配布を望むチームには、horizOnがマネージドサービスとしてリモート設定を提供しています。ダッシュボードまたはAPIを通じてフィーチャーフラグ、ゲーム設定、チューニングパラメータを定義すると、プラットフォームがゲームクライアントへの配布を処理します。書くべきエッジワーカーも維持するものもなく、KVネームスペースサイズの制約を考慮する必要もありません——ただし、基盤となるレプリケーションエンジンとレイテンシプロファイルの制御は少なくなります。

トレードオフは古典的なビルド対バイの軸です。KV Instantはエッジでの生のパフォーマンスと完全な制御を提供します。マネージドサービスはより速い統合時間とより少ない運用サーフェスエリアを提供します。設定配布がスタジオの中核能力かインフラストラクチャのオーバーヘッドかに基づいて選択してください。

分散ゲームクライアント全体で設定の古さを検出する必要がある場合、上記のランクブックセクションのロギングとクエリパターンは、どの設定バックエンドを選択しても機能します。診断レイヤーはトランスポートから独立しています。


まとめ: ゲームに追いつく設定読み取り

KV Instantは「小さく、重要で、グローバルに読み取られる設定データ」という特定のパターンにとって意味のあるアップグレードです。ゲームバックエンドでは、このパターンはフィーチャーフラグ、エコノミーチューニング、イベントスケジュール、メンテナンススイッチ、ビルドバージョンゲートに直接対応します。

数値はマーケティングの丸めではありません: 300以上のエッジロケーションで1.62msのp99読み取りと256msのp99書き込みレプリケーション。APIは従来のWorkers KVと同一です。制約(1MB、10,000キー、1書き込み/秒)は明確に定義されており、ユースケースに適切です。

ゲームが現在集中ストアから設定を読み取り、レイテンシを避けるためにクライアント側でキャッシュしている場合、その古さのウィンドウがまだ許容可能かどうかを評価してください。競技ゲームやリアルタイムエコノミーチューニングを備えたライブサービスゲームでは、答えはますます「いいえ」になっています。

KV Instantプライベートベータに申し込み、最もレイテンシに敏感な設定でテストネームスペースをセットアップし、得られる伝播ヘッドルームを測定してください。数値がCloudflareの報告と一致する場合、古い設定インシデントのクラスを完全に排除する明確な道筋があります。

設定アーキテクチャやバックエンドトポロジーについてセカンドオピニオンが必要ですか?horizOnドキュメントをチェックしてください——プラットフォームは設定配布、クラッシュレポート、プレイヤーセッション管理を処理するため、インフラストラクチャのランクブックではなくゲームプレイの出荷に集中できます。


ソース: Workers KV Instantの紹介 — Quicksilver搭載

このダッシュボードは以下のチームによって愛情を込めて作られています Projectmakers

© 2026 projectmakers.de

unknown-v1.104.0 / unknown-v--