個人開発のバックエンドを Cloudflare Workers に寄せた結果、月額数円〜数十円で安定稼働している。無料枠が太く、コールドスタートが実質無視できるためである。構成要素は Workers(実行)、KV(分散KVS)、D1(SQLite 互換)、R2(S3 互換オブジェクトストレージ)の4点で、それぞれ使いどころが明確に異なる。
料金構造の要点
Workers は無料プランで1日10万リクエストまで、Paid プランは月5ドルで1000万リクエスト/月が含まれる。KV は読み取りが安く書き込みが高い典型的な読み取り特化の料金。D1 は行数課金で読み取り2500万行/日まで無料、R2 は S3 と違い エグレス無料 が最大の特徴である。
個人サービスの規模であれば Paid プランに上げても、実費は月数十円〜数百円で収まる。
4つのストレージの使い分け
KV — 読み取り頻繁・書き込み少の設定値
KV は結果整合性で、書き込みから数十秒〜1分ほど世界中のエッジに伝播する。このため設定値、機能フラグ、セッションキャッシュのような 頻繁に読み、たまに書く 用途に向く。
export default {
async fetch(req, env) {
const flag = await env.MY_KV.get("feature_new_ui");
return new Response(flag ?? "off");
}
}
D1 — リレーショナルが必要な本体データ
D1 は SQLite をベースにしたエッジ分散 DB で、普通の SQL が書ける。ユーザーテーブル、投稿テーブルのような関係データは D1 に置く。プリペアドステートメントが必須である。
const { results } = await env.DB
.prepare("SELECT id, title FROM posts WHERE user_id = ? LIMIT 20")
.bind(userId)
.all();
R2 — 画像・添付ファイル
R2 はエグレス無料のおかげで、画像配信やバックアップ置き場として極めて安い。Workers から直接バイトストリームで読み書きでき、署名付き URL も発行できる。
await env.MY_BUCKET.put(`users/${id}/avatar.png`, req.body, {
httpMetadata: { contentType: "image/png" }
});
Workers 本体 — ロジックとルーティング
Hono などの軽量フレームワークを使うと、Express 感覚で書ける。bundle サイズ上限(Free 1MB, Paid 10MB)に注意する。
実運用で詰まる点
D1 は1トランザクションあたりの書き込み数、KV は1キーあたりのサイズ上限(25MiB)、Workers は1リクエストあたりの CPU 時間制限がそれぞれある。長い処理は Queues や Durable Objects に逃がすのが定石である。ログは wrangler tail で確認できるが、本番運用では Logpush で外部に出す。
まとめ
KV はホットな読み取り、D1 はリレーショナル、R2 は大きなオブジェクト、Workers はロジック。この4分類を守るだけで、個人サービスは月数円〜数十円に収まる。エグレス無料の R2 は特にコスト面で他クラウドに対して圧倒的な優位がある。