cloudflare-caution について
cloudflare-cautionは、Cloudflareアプリの請求を管理したい開発者向けのスキルです。再利用できる処理のキャッシュ、過剰な利用の抑制、本番データに基づく費用見積もりを扱います。
主な機能
- 01再利用可能な結果のキャッシュ
- 02CPUとレートの上限設定
- 03書き込みと一覧操作の削減
- 04ログとトレースのサンプリング
- 05使用量の見積もりと検証
活用シーン
- 01公開ページの静的配信設計
- 02ボットのトラフィックからAPIを保護
- 03再試行とキューループの制限
- 04見積もりと本番使用量の照合
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ masseater/ skills --skill cloudflare-cautionインストール後、Claude Code で/cloudflare-cautionを入力して読み込まれたか確認します。
同梱ファイルreferences/pricing-traps.md
詳細
プロジェクトの README よりcloudflare-caution
Cloudflare で請求が膨らまない設計にするための規則である。
- 結果が同じになる処理を、リクエストのたびに動かさない
- 暴走したときに止まる仕組みを、コードと設定に入れる
- 課金される単位で費用を見積もり、本番の使用量で確かめる
この skill が必要な理由と達成したい状態
この skill が必要な理由は、Cloudflare の課金がリクエスト、行、操作、ログのイベントといった細かい単位の従量で、しかも支出に上限が無いことにある。どの単位も 1 回あたりは安いので、書いている時点では気にならない。けれど閲覧のたびに SSR や API や DB を動かす設計では、費用がアクセス数に比例して伸びる。ループや再試行のバグがあれば、その回数がそのまま請求になる。予算アラートは知らせるだけで、止めてはくれない。実際に、Queue への再投入のループで 3 万ドルを超える請求が来た例がある(記事)。
この skill で達成したい状態は、1 回のアクセスにかかる費用が設計の段階で決まっていることである。バグやボットで想定を外れても、請求になる前にコードと設定が止める。
単価と課金の仕組み
pricing-traps も読むこと。課金の単位ごとの単価、上限が無いこと、静的アセットが Worker を起動しない条件、高額請求の実例をまとめている。
同じ結果の作り置き
閲覧のたびに同じものを作り直すと、Worker の起動、CPU 時間、DB の行がアクセス数に比例して課金される。作り置けるものは作り置いて配る。
- 誰が見ても同じ公開ページは、ビルド時にプリレンダーして静的アセットで配る。静的アセットへのリクエストは Worker を起動しないので課金されない
assets.run_worker_firstは、認証や API のパスだけに絞る。全体に掛けると、静的アセットへのリクエストもすべて Worker の課金に変わる- 閲覧者ごとに変わる部分だけを動的にする。ページ全体を動的にしない
- 動的なデータは、変わる頻度に合わせて CDN のキャッシュ、Cache API、KV に置く。リクエストのたびに D1 や外部 API を呼ばない
- クライアントでは、データが変わらない間は再取得しない。TanStack Query なら
staleTimeを設定する
暴走の歯止め
支出の上限が無いので、止める仕組みは自分で入れるしかない。
- Worker には
limits.cpu_msを付ける。値は本番の CPU 時間の p99 を測って、その少し上にする。上限まで上げると、無限ループがそのまま請求になる - 公開する API、認証、書き込みの口の前段には、レート制限を置く。ボットの大量アクセスは、レート制限が無ければすべて課金される
- レート制限は、ゾーンを持つリポでは WAF のレート制限ルールで、持たないリポでは Workers の Rate Limiting バインディングで掛ける
- Queue の consumer、Durable Object の alarm、再試行の処理は冪等にする。自分自身を再投入しない
- 再投入と再試行には回数の上限を付ける
- アカウントに予算アラートを設定する。止めるためではなく、早く気づくためである
書き込みと操作の削減
書き込みと一覧の操作は、読み取りより 1 桁から 3 桁高い。
- KV の書き込み、D1 と Durable Objects の行の書き込みは、まとめて書く
- 値が変わっていなければ書かない
- KV の
list()をリクエストのたびに呼ばない。キーで直接引けるように設計する - Durable Object は、WebSocket Hibernation と alarm を使って眠らせる。起きている間は、使っていなくても 128 MB 分の時間が課金される
- Durable Object を
setTimeoutや外向きの接続で起こしたままにしない - R2 の Infrequent Access は、書き込みや読み取りの多い小さいファイルに使わない。操作の単価が Standard より高い
ログとトレースの間引き
ログもトレースも、量に応じて課金される。
- 全リクエストのログを Cloudflare に保存し続けない。必要な量だけを
head_sampling_rateでサンプリングする - 外部へ送るだけなら
persist: falseにする
見積もりと本番での確認
measure-dont-guess に従う。
- 設計を決める前に、想定のアクセス数に 1 回あたりの Worker の起動・行・操作・ログの数を掛けて、月額を見積もる
- デプロイの後は、ダッシュボードの Billable Usage か GraphQL Analytics API で本番の使用量を見る。見積もりとずれていれば、設計を見直す