infra-platform-cloudflare-workers について
Cloudflare Workers 上で TypeScript と JavaScript のアプリを構築するためのスキルガイドです。Wrangler の設定に加え、エッジストレージ、ステートフル処理、ルーティング、バックグラウンド処理を扱います。
主な機能
- 01Wrangler の設定とデプロイ
- 02Cloudflare サービスの型付きバインディング
- 03KV、D1、R2 の利用パターン
- 04Durable Objects と WebSocket
- 05キュー、cron、サービスバインディング
- 06ストリーミングとメモリ制限の指針
活用シーン
- 01Cloudflare Workers で API を構築
- 02KV、D1、R2 にデータを保存
- 03Durable Objects でリアルタイム機能を構築
- 04定期処理やキュー処理を設定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ agents-inc/ skills --skill infra-platform-cloudflare-workersインストール後、Claude Code で/infra-platform-cloudflare-workersを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
metadata.yamlreference.mdexamples/core.mdd1.mddurable-objects.mdkv.mdr2.mdrouting.md詳細
Cloudflare Workers のパターン
クイックガイド: Cloudflare Workers は、V8 アイソレート(コンテナではありません)を使用して、Cloudflare のグローバルエッジネットワーク上で TypeScript/JavaScript を実行します。設定には
wrangler.jsonc、ローカル開発にはwrangler dev、本番環境へのデプロイにはwrangler deployを使用します。envパラメーター上の型安全なバインディングを通じて、KV、D1、R2、Queues、Durable Objects、Workers AI にアクセスします。wrangler typesを実行して、Envインターフェースを自動生成します。大きなペイロードはストリーミングしてください。Workers のメモリ上限は 128 MB です。リクエストごとの状態をモジュールレベルの変数に保存しないでください。
<critical_requirements>
重要:このスキルを使用する前に
(wrangler types を実行して Env インターフェースを生成する必要があります。バインディングの型を手書きしてはいけません)
(新しいプロジェクトでは wrangler.jsonc を使用する必要があります。Cloudflare は JSON 設定を推奨しており、一部の機能は JSON でのみ使用できます)
(大きなリクエスト/レスポンスボディはストリーミングする必要があります。ペイロード全体をメモリにバッファリングしてはいけません(上限は 128 MB))
(モジュールレベルの可変状態は使用しないでください。Workers はリクエスト間で V8 アイソレートを再利用するため、リクエスト間でデータが漏洩するおそれがあります)
(Cloudflare のサービス(KV、D1、R2、Queues)にはバインディングを使用する必要があります。Workers 内から REST API を使用してはいけません)
</critical_requirements>
例
- コアのセットアップと設定 — wrangler.jsonc、プロジェクトの初期化、fetch ハンドラー、シークレット、複数環境、CI/CD、テスト
- KV ストレージ — KV バインディング、型付きの get/put、TTL、stale-while-revalidate キャッシュ
- D1 データベース — D1 バインディング、パラメーター化クエリ、一括操作、マイグレーション、CRUD API
- R2 オブジェクトストレージ — R2 バインディング、ストリーミングによるファイルのアップロード/ダウンロード/削除
- Durable Objects — DO クラス、SQLite、RPC、レートリミッター、WebSocket チャット
- ルーティングとミドルウェア — API フレームワークの統合、ミドルウェア、キュー、cron、サービスバインディング、AI、ストリーミング
- クイックリファレンス — Wrangler CLI コマンド、バインディングの型シグネチャ、設定テンプレート、CPU 制限
自動検出: Cloudflare Workers、wrangler、wrangler.toml、wrangler.jsonc、Workers KV、Cloudflare KV、D1 データベース、R2 バケット、Durable Objects、Cloudflare Queues、Workers AI、サービスバインディング、miniflare、compatibility_date、compatibility_flags、nodejs_compat、cloudflare:workers、ExportedHandler、DurableObject、wrangler dev、wrangler deploy、wrangler types、Cloudflare Pages Functions、エッジワーカー、CF Worker
使用する場合:
- Cloudflare のエッジネットワークに TypeScript/JavaScript をデプロイする場合
- ローカル開発とデプロイ用に Wrangler CLI を設定する場合
- Cloudflare のバインディング(KV、D1、R2、Queues、Durable Objects、Workers AI)を使用する場合
- フレームワーク(例:Hono)を使って Workers 上に API を構築する場合
- Durable Objects と WebSockets でリアルタイム機能を実装する場合
- cron トリガーとスケジュール済みハンドラーを設定する場合
- ワーカー間通信のためにサービスバインディングを設定する場合
- 環境変数、シークレット、複数環境へのデプロイを管理する場合
使用しない場合:
- CPU 時間制限を超える長時間実行のコンピューティングタスク(従来型サーバーまたは Workflows を使用してください)
- Hyperdrive を使用せずに外部データベースへの永続的な TCP 接続を必要とするアプリケーション
- リクエストごとに 128 MB を超えるメモリを必要とするワークロード
対象となる主なパターン:
- Wrangler の設定(
wrangler.jsonc)とプロジェクトのセットアップ - fetch ハンドラー、スケジュール済みハンドラー、キューハンドラー
- KV キー・バリュー型ストレージ(キャッシュ、設定、セッションデータ)
- D1 SQLite データベース(エッジ上のリレーショナルデータ)
- R2 の S3 互換オブジェクトストレージ(ファイル、アップロード、アセット)
- Durable Objects(ステートフルなエッジコンピューティング、WebSockets、調整)
- Cloudflare Queues(非同期メッセージ処理)
- Workers AI(エッジでの推論)
- 型付きバインディングを使ったフレームワーク統合(Hono の例)
- 環境変数、シークレット、複数環境の設定
- サービスバインディング(ワーカー間 RPC)
- cron トリガーとスケジュール済みワーカー
- ストリーミングとパフォーマンスの最適化
- Workers ネイティブのテストプールを使ったテスト
## 設計思想
Cloudflare Workers は、世界中の 300 以上のデータセンターで、コンテナではなく V8 アイソレート上で動作します。コールドスタートは発生せず、起動時間は 5ms 未満です。プログラミングモデルは従来のサーバーとは根本的に異なります。
- API よりバインディング - Cloudflare のサービス(KV、D1、R2、Queues)には、REST API を呼び出すのではなく、
envパラメーター上のプロセス内バインディングを通じて直接アクセスします。バインディングではネットワークホップも認証のオーバーヘッドも発生しません。 - デフォルトではステートレス - リクエストごとに新しい実行コンテキストが割り当てられます。Workers は V8 アイソレートを再利用するため、モジュールレベルの変数はリクエスト間で保持されます。これは機能ではなく、バグの原因になります。
- すべてをストリーミング - Workers のメモリ上限は 128 MB です。データをバッファリングせず、
TransformStreamとpipeToを使ってリクエストとレスポンスのボディをストリーミングします。 - エッジファーストのアーキテクチャ - コードはユーザーに最も近い場所で実行されます。調整や状態管理が必要な場合は Durable Objects を、永続化には D1/KV/R2 を使用します。
Workers を使用する場面:
- API エンドポイント、ミドルウェア、リクエストルーティング
- キャッシュレイヤーとコンテンツ変換
- Webhook の受信とイベント処理
- リアルタイムの共同作業(Durable Objects と併用)
- フルスタックアプリケーション(Workers Static Assets または Pages を使用)
Workers を使用しない場面:
- 制限を超える CPU 負荷の高い計算(リクエストごとに無料プランは 10ms、有料プランは 30s)
- 128 MB を超えるメモリが必要なワークロード
- データベースへの永続的な接続が必要なアプリケーション(プロキシとして Hyperdrive を使用)
- 制限を超えて長時間実行されるバックグラウンドジョブ(永続的な実行には Workflows を使用)
コアパターン
パターン 1:プロジェクトのセットアップと Wrangler の設定
Workers プロジェクトはすべて wrangler.jsonc から始まります。Cloudflare は JSON 形式を推奨しています。一部の新しい機能は JSON のみで利用できます。バインディングを変更した後は wrangler types を実行して、Env インターフェイスを再生成してください。
// wrangler.jsonc
{
"$schema": "./node_modules/wrangler/config-schema.json",
"name": "my-api",
"main": "src/index.ts",
"compatibility_date": "2025-09-15",
"compatibility_flags": ["nodejs_compat"],
"observability": { "enabled": true },
"placement": { "mode": "smart" },
"upload_source_maps": true,
}
プロジェクトの初期化、複数環境の設定、シークレット管理、CI/CD、テストのセットアップについては、examples/core.md を参照してください。
パターン 2:Fetch ハンドラー(リクエスト/レスポンス)
Fetch ハンドラーは HTTP リクエストのエントリーポイントです。型安全性を確保するため、satisfies ExportedHandler<Env> を使用してください。
import type { ExportedHandler } from "cloudflare:workers";
export default {
async fetch(request, env, ctx): Promise<Response> {
const url = new URL(request.url);
if (url.pathname === "/health") {
return Response.json({ status: "healthy" });
}
return new Response("Not Found", { status: 404 });
},
} satisfies ExportedHandler<Env>;
モジュールレベルの変数に変更可能な状態を保存しないでください。V8 アイソレートが再利用されると、リクエスト間でデータが漏洩するおそれがあります。CORS とルーティングを含む完全なハンドラーについては、examples/core.md を参照してください。
パターン 3:KV キー/値ストレージ
KV は、読み取りが多いワークロード向けの結果整合性を持つキー/値ストアです。型付きの get<T>(key, "json") を使用し、必ず expirationTtl を設定し、ブロッキングしない書き込みには ctx.waitUntil() を使用してください。
const CACHE_TTL_SECONDS = 3_600;
const profile = await env.CACHE.get<UserProfile>(`user:${id}`, "json");
ctx.waitUntil(
env.CACHE.put(`user:${id}`, JSON.stringify(data), {
expirationTtl: CACHE_TTL_SECONDS,
}),
);
使用する場面: 結果整合性を許容できる、読み取りが多いワークロード(設定、キャッシュ、機能フラグなど。伝播には約 60 秒かかります)。
使用しない場面: リレーショナルデータ(D1 を使用)、同じキーへの頻繁な書き込み、強い整合性が必要な場合(Durable Objects を使用)。
stale-while-revalidate パターンとキャッシュの完全な例については、examples/kv.md を参照してください。
パターン 4:D1 SQLite データベース
D1 はエッジで利用できるサーバーレス SQLite です。SQL インジェクションを防ぐため、必ず prepare().bind() によるパラメーター化クエリを使用してください。複数のステートメントをアトミックに実行するには batch() を使用してください。読み取りレプリケーションが有効な場合に読み取りレプリカとの整合性を確保するには、withSession() を使用してください。
const user = await db
.prepare("SELECT * FROM users WHERE email = ?")
.bind(email)
.first<User>();
const { results } = await db
.prepare("SELECT * FROM users LIMIT ? OFFSET ?")
.bind(DEFAULT_PAGE_SIZE, offset)
.all<User>();
マイグレーション、バッチ処理、CRUD API の完全な例については、examples/d1.md を参照してください。
パターン 5:R2 オブジェクトストレージ
R2 は、エグレス料金がかからない S3 互換ストレージです。R2 のボディは必ずレスポンスに直接ストリーミングしてください。大きなオブジェクトに対して .arrayBuffer() や .text() を呼び出してはいけません。
const object = await env.BUCKET.get(key);
if (!object) return new Response("Not Found", { status: 404 });
const headers = new Headers();
object.writeHttpMetadata(headers);
return new Response(object.body, { headers }); // Stream directly
コンテンツタイプの検証と一覧表示の操作を含むファイルサービスについては、examples/r2.md を参照してください。
### パターン 6:Durable Objects(ステートフルなエッジコンピューティング)
Durable Objects は、シングルスレッドで強い一貫性を持つコンピューティングを提供します。各インスタンスは SQLite ストレージを備えています。RPC メソッド(fetch ではありません)と、スキーマ移行用の blockConcurrencyWhile を使用してください。
import { DurableObject } from "cloudflare:workers";
export class Counter extends DurableObject<Env> {
constructor(ctx: DurableObjectState, env: Env) {
super(ctx, env);
ctx.blockConcurrencyWhile(async () => {
this.ctx.storage.sql.exec("CREATE TABLE IF NOT EXISTS ...");
});
}
async increment(name: string): Promise<number> {
/* RPC method */
}
}
使用する場合: 調整(チャット、コラボレーション)、エンティティごとの状態(セッション、ゲームインスタンス)、WebSocket 接続、レート制限。
使用しない場合: ステートレスなリクエスト、高いファンアウト、グローバルなレート制限(ボトルネックになります)。
レートリミッターと、ハイバネーションを使用した WebSocket チャットについては、examples/durable-objects.md を参照してください。
パターン 7:キュー、Cron、サービスバインディング、Workers AI
キューは、少なくとも 1 回の配信と設定可能な再試行により、プロデューサーとコンシューマーを分離します。Cron トリガーは、スケジュールに従って Workers を呼び出します。サービスバインディングにより、コストなしで Worker 間の呼び出しが可能になります。Workers AI は、Cloudflare の GPU ネットワーク上で推論を実行します。
これらすべてのパターンの完全な設定とコード例については、examples/routing.md を参照してください。
パターン 8:API フレームワークとの統合
構造化された API には、型付きバインディングを備えたルーティングフレームワークを使用してください。スケジュールハンドラーやキューハンドラーと併せて、フレームワークの fetch ハンドラーをエクスポートします。
import { Hono } from "hono";
const app = new Hono<{ Bindings: Env }>();
app.get("/users/:id", async (c) => {
const user = await c.env.DB.prepare("SELECT * FROM users WHERE id = ?")
.bind(c.req.param("id"))
.first();
return user ? c.json(user) : c.json({ error: "Not found" }, 404);
});
export default app;
ミドルウェア、エラー処理、複数ハンドラーの設定を備えた本番環境向け API については、examples/routing.md を参照してください。
パフォーマンスの最適化
リクエスト処理
| 手法 | 効果 |
|---|---|
Smart Placement("mode": "smart") | バインディングの配置場所に基づき、最適なデータセンターへルーティングします |
| ストリーミングレスポンス | 128 MB のメモリ制限を回避し、TTFB を改善します |
バックグラウンド処理に ctx.waitUntil() を使用 | レスポンスをすぐに返し、その後、非同期処理を実行します |
nodejs_compat フラグ | Node.js の組み込みモジュール(crypto、buffer、stream)にアクセスできます |
ストレージのパフォーマンス
| ストレージ | 読み取り | 書き込み | 一貫性 | 最適な用途 |
|---|---|---|---|---|
| KV | 高速(エッジでキャッシュ) | 低速(伝播に約 60 秒) | 結果整合性 | キャッシュ、設定、フラグ |
| D1 | 中程度 | 中程度 | 強い(リージョン単位) | リレーショナルデータ、クエリ |
| R2 | 中程度 | 中程度 | 強い | ファイル、バイナリデータ、アップロード |
| Durable Objects | 高速(メモリ内) | 高速(SQLite) | 強い(シングルスレッド) | 調整、リアルタイム処理 |
外部データベース向け Hyperdrive
Cloudflare の外部にある PostgreSQL/MySQL に接続する場合は、必ず Hyperdrive を使用してください。データベースの近くにコネクションプールを維持するため、リクエストごとに発生する TCP/TLS のオーバーヘッドをなくせます。
CPU 時間の制限
| プラン | リクエストあたりの CPU 時間 |
|---|---|
| Free | 10 ms |
| Paid | 30 秒(デフォルト)。最大 15 分まで設定可能 |
| Cron トリガー | 15 分 |
<decision_framework>
選択の指針
ストレージプリミティブの選び方
What kind of data?
|
+-- Key-value pairs (cache, config, sessions)
| +-- Read-heavy, eventual consistency OK --> KV
| +-- Strong consistency needed --> Durable Objects
|
+-- Relational data with queries
| +-- Edge-native SQLite --> D1
| +-- External PostgreSQL/MySQL --> Hyperdrive
|
+-- Files and blobs (images, documents)
| +-- S3-compatible storage --> R2
|
+-- Coordination state (chat, multiplayer, collaboration)
| +-- Single-threaded consistency --> Durable Objects
|
+-- Message passing / background work
+-- Simple fan-out, buffering --> Queues
+-- Multi-step durable execution --> Workflows
Workers と Pages の選び方
What are you building?
|
+-- API only (no frontend) --> Workers
|
+-- Static site + API --> Pages with Functions
|
+-- Full-stack with SSR --> Pages (framework) or Workers + Static Assets
|
+-- Background processing / cron --> Workers (Pages lacks cron support)
|
+-- Real-time / WebSockets --> Workers + Durable Objects
Durable Objects と D1 の使い分け
Do you need coordination between concurrent requests?
|
+-- YES (chat, game, collaboration) --> Durable Objects
| +-- Single-threaded, no race conditions
| +-- WebSocket support with hibernation
| +-- Per-entity sharding (one DO per room/session)
|
+-- NO (CRUD, reporting, querying) --> D1
+-- Full SQL support
+-- Cross-entity queries
+-- Traditional database patterns
</decision_framework>
## 統合ガイド
Cloudflare プラットフォームサービス:
- Hyperdrive:外部 PostgreSQL/MySQL 用のコネクションプーリングプロキシ。リクエストごとに発生する TCP/TLS のオーバーヘッドを解消します
- Vectorize:Workers AI と連携する、埋め込みとセマンティック検索のためのベクトルデータベース
- Cloudflare Pages:Workers を利用した関数を備えた、フルスタックアプリ向けの静的サイトホスティング
- GitHub Actions:CI/CD デプロイには
cloudflare/wrangler-action@v3を使用します
フレームワークと ORM の互換性:
Workers は、V8 ランタイムをサポートするエッジ最適化フレームワークや ORM と互換性があります。fetch ハンドラーをエクスポートするフレームワークであれば動作します(Hono、itty-router など)。D1 は、SQLite をサポートするあらゆる ORM で動作します(ORM の Workers 互換性に関するドキュメントをご確認ください)。
テスト:
実際の Workers ランタイム内で実際のバインディング(KV、D1、R2)を使用してテストを実行するには、@cloudflare/vitest-pool-workers を使用します。テスト設定については、examples/core.md をご覧ください。
危険信号
優先度の高い問題:
- リクエスト単位のデータをモジュールレベルの変数に保存する(V8 アイソレートが再利用されるため、リクエスト間でデータが漏えいします)
.text()/.arrayBuffer()でリクエスト/レスポンス本文全体をバッファリングする(メモリ上限は 128 MB です)wrangler typesを実行せずにEnvインターフェースを手書きする(設定とコードに不整合が生じます)- Workers 内から KV/D1/R2/Queues の REST API を使用する(バインディングを使わず、不要なレイテンシと認証のオーバーヘッドが発生します)
wrangler.jsonc、ソースコード、環境変数にシークレットを格納する(wrangler secret putを使用してください)- すべてのトラフィックに対して、単一のグローバル Durable Object を作成する(約 1000 req/sec でボトルネックになります)
優先度が中程度の問題:
- 新規プロジェクトで
wrangler.tomlを使用する(JSON 形式が推奨されており、一部の機能は JSON のみで使用できます) - 古い
compatibility_dateを使用する(ランタイムの改善やバグ修正が反映されません) observability設定がない(本番環境の Workers はログ/トレースがなければブラックボックスになります)- fetch ハンドラーで
ctxを分割代入する(thisバインディングが失われ、ctx.waitUntilが "Illegal invocation" をスローします) - D1 クエリに
prepare().bind()ではなくexec()を使用する(パラメーター化されず、SQL インジェクションの危険があります) - Durable Objects で WebSocket のクローズを相互に通知しない(1006 エラーが発生します)
よくある間違い:
- KV は結果整合性である(伝播に約 60 秒かかる)ことを忘れ、書き込み後すぐに読み取れると想定する
- セキュリティ上重要なトークンに
Math.random()を使用する(crypto.randomUUID()またはcrypto.getRandomValues()を使用してください) - レスポンス送信後のバックグラウンド処理に
ctx.waitUntil()を使わない(レスポンス送信時に処理がキャンセルされる場合があります) - シークレットを
crypto.subtle.timingSafeEqual()ではなく===で比較する(タイミングサイドチャネル攻撃の危険があります) - エラー処理として
passThroughOnException()を使用する(バグが隠れるため、明示的な try/catch を使用してください) - Promise が放置される(await されない、返されない、
waitUntil()に渡されない)ことで、エラーが気づかれないまま発生します。開発時に検出するには@typescript-eslint/no-floating-promisesを有効にしてください
注意点とエッジケース:
- バインディング(KV、D1、R2 など)は Wrangler の環境間で継承されません。環境ごとに再宣言する必要があります
wrangler devはデフォルトでローカルシミュレーションを使用します。実際の Cloudflare サービスに対してテストするには--remoteを使用してください- D1 のバッチ操作は並列ではなく順次実行されますが、アトミックです
- Durable Objects のインメモリ状態はエビクション時に失われます。重要なデータは必ず、まず SQLite に永続化してください
- DO のストレージ書き込みの間に不要な
awaitを挟むと、書き込みの集約が妨げられます。間にawaitを挟まなければ、バッチ書き込みはアトミックに実行されます - DO のアラームハンドラーは複数回実行される場合があります。冪等になるよう設計してください
- すべてのリクエストで
blockConcurrencyWhile()を使用するとスループットが約 200 req/sec に制限されます。初期化時にのみ使用してください - 無料プランの Workers では、リクエストごとの CPU 時間制限は 10 ms です(実時間ではありません。I/O 待機時間は無料です)
- Cron トリガーの変更がグローバルに反映されるまで、最大 15 分かかります
.dev.varsファイルはローカルのシークレット専用であり、必ず gitignore に追加してくださいenvパラメーターはランタイムによってリクエストごとに提供されます。バインディングへの参照や派生オブジェクトをモジュールスコープでキャッシュしないでください
</red_flags>
<critical_reminders>
重要な注意事項
(wrangler types を実行して Env インターフェースを生成する必要があります。バインディングの型を手書きしてはいけません)
(新規プロジェクトでは wrangler.jsonc を使用する必要があります。Cloudflare は JSON 設定を推奨しており、一部の機能は JSON のみで使用できます)
(大きなリクエスト/レスポンス本文はストリーミングする必要があります。ペイロード全体をメモリにバッファリングしてはいけません(上限は 128 MB です))
(モジュールレベルの可変状態は避ける必要があります。Workers はリクエスト間で V8 アイソレートを再利用するため、データが漏えいします)
(Cloudflare サービス(KV、D1、R2、Queues)にはバインディングを使用する必要があります。Workers 内から REST API を使用してはいけません)
これらのルールに従わないと、メモリクラッシュ(バッファリング)、データ漏えい(モジュール状態)、型の不整合(手書きの Env)、不要なレイテンシ(バインディングではなく REST API を使用)、シークレットの露出(設定にシークレットを保存)が発生します。
</critical_reminders>