この記事についてClaude(Anthropic)との共同編集により作成されました。
要約
- 比較記事で目星をつけた Cloudflare Pages を、採用前に個別深掘りしておいたメモ
- Pages は静的特化、Workers はフル機能。両者はエッジネットワーク(300+拠点)の上に乗っている共通基盤
- Pages Functions の正体は Workers ランタイム。ただしバインディングは Workers のサブセット
- 採用後の今、ダッシュボードの新規作成はもう Workers 一択になっていた(既存 Pages はそのまま運用可)
- D1 / KV / R2 まで揃っていて、Free 枠でもフルスタックは組める
- 非アクティブ停止がない・コールドスタートほぼゼロ・R2 エグレス無料 が Supabase との大きな差
- セキュリティヘッダーはデフォルトでは付かないので
_headersを自分で書く
先月、無料で使える Web ホスティングサービスを横並びで比較する記事を書いて、そこで自分の用途には Cloudflare Pages が一番合うという結論に至った(Webアプリを無料で公開したいときに使えるホスティングサービスを商用利用と放置耐性で比較してみた)。比較記事の段階ですでに「Cloudflare Pages を採用する方向で進める」とまでは決めていたが、そこから実際に採用するまでの間に、もうワンランク踏み込んで個別調査をしている。具体的には、Pages Functions の中身は何か、Workers との関係はどうなっているか、無料枠で本当にどこまで作れるのか、というあたり。
AI コーディングでサクッとサービスを組み立てるとき、土台のプラットフォームの素性を知らないままだと、後から「思ってたのと違う」が出てくる。比較で表面の選定をしたら、深掘りで内部を抑えておく、というのを習慣にしておきたい。
その深掘りメモを記事化しようと思いつつ後回しになっていたので、今になって整理する^1。
アーキテクチャの基本 — 300+ エッジ拠点に分散配置される
Cloudflare Pages は世界 300 以上のエッジロケーションに静的アセットを分散配置するサービス^2。ユーザーに最も近いエッジから配信するため、グローバル TTFB(Time to First Byte)は条件次第で 60ms を切る計測結果も出ている^3。
プロジェクトの典型構成はこうなる。
├── public/ ← 静的アセット(HTML, CSS, JS, 画像)├── functions/ ← Pages Functions(サーバーサイドコード)│ ├── api/│ │ └── [endpoint].ts│ └── _middleware.ts├── _headers ← カスタムHTTPヘッダー定義├── _redirects ← リダイレクトルール定義└── wrangler.toml ← Wrangler設定(任意)public/ 以下は CDN にキャッシュされる静的アセット。functions/ 以下のファイルが Pages Functions として扱われ、ファイルシステムのパスがそのまま API ルートになる^4。functions/api/hello.ts を置けば /api/hello で叩ける。
デプロイは 3 方式 — 基本は Git 連携
Pages のデプロイ方式は 3 つある^5。
- Git 連携(推奨): GitHub / GitLab と連携し、push のたびに自動ビルド・デプロイ。プロダクションブランチへの push は本番、その他のブランチは一意の URL でプレビュー
- Direct Upload: 事前にビルドしたディレクトリを Wrangler CLI (
wrangler pages deploy)または管理画面から直接アップロード - C3 CLI(
npm create cloudflare@latest): 新規プロジェクトのスキャフォールディングからデプロイまで一気通貫
注意点として、Direct Upload を選ぶと後から Git 連携に切り替えられない^5。プロジェクト作成時の選択は慎重にやる必要がある。基本は Git 連携を選んでおけば、PR ごとにプレビュー URL が発行され、ロールバックも UI で完結する。
Pages Functions の正体は Workers — ただしバインディングはサブセット
Pages Functions は単独の独自ランタイムではなく、Cloudflare Workers ランタイム上で動くサーバーサイドコードである^4。ここを理解していないと、Pages を選んだあとに「Workers なんとかが使えなくて困った」ということが起きる。
functions/api/hello.ts の中身はこうなる。
export const onRequestGet: PagesFunction = async (context) => { return new Response("Hello, World!");};onRequestGet, onRequestPost のようにメソッドごとに、または onRequest で全メソッド一括で書ける。_middleware.ts を置けば認証チェックや CORS 付与などを横断的に処理できる。
問題は バインディング(Cloudflare サービスへの接続)が Workers のフルセットではなくサブセットだけ という点だ^6。
| バインディング | Pages Functions | Workers |
|---|---|---|
| KV / D1 / R2 / Durable Objects | ✅ | ✅ |
| AI / Vectorize / Queues Producer | ✅ | ✅ |
| Queues Consumer | ❌ | ✅ |
| Email Workers | ❌ | ✅ |
| Image Resizing | ❌ | ✅ |
| Rate Limiting | ❌ | ✅ |
| Stream / Secrets Store / Workflows | ❌ | ✅ |
データストアまわりは Pages Functions でも揃っているが、メール送受信・画像変換・レート制限・ワークフロー系は Workers にしかない。あとから「これも欲しい」となったときに Workers に移ることを考慮しておく必要がある。
なお functions/ ディレクトリの代わりに _worker.js を直接置く Advanced Mode もあり、その場合は Workers の Module Worker 構文をフルに使える^7。
Pages と Workers は「収束(converging)」中 — 新規はもう Workers 一択になっていた
Cloudflare は 2023 年に Pages と Workers の体験を統一する方針を発表していて^8、機能の重複・拡張が続いた結果、両者をひとつに収束させる動きが進んでいる。公式は Pages から Workers への移行ガイドも出している^9。
調査時点(5月中旬)では「現時点では Pages の新規利用も引き続きサポートされている」というスタンスだったのだが、採用してしばらく運用している今(2026年6月)あらためてダッシュボードを開くと、新規プロジェクト作成のデフォルトが Workers になっていて、Pages を新規で作る導線が事実上消えていた。既存 Pages プロジェクトはそのまま運用継続できているので、過去の選定が即座に詰むわけではないが、これから新規に Cloudflare で動的アプリを立てるなら 最初から Workers を選ぶのが素直、という状況になっている。
その流れで気にしたいのが、Workers 側にしかない機能 だ^10。
| 機能 | Workers | Pages |
|---|---|---|
| Cron Triggers(定期実行) | ✅ | ❌ |
| Gradual Deployments(段階的デプロイ) | ✅ | ❌ |
| Workers Logs / Logpush / Tail Workers | ✅ | ❌ |
| Source Maps | ✅ | ❌ |
| Image Resizing | ✅ | ❌ |
| Rate Limiting | ✅ | ❌ |
| Queue Consumers | ✅ | ❌ |
定期バッチ・段階リリース・本格的なログ運用が要るなら、Pages では足りない場面が出てくる。逆に Pages にしかない強みはというと、Cloudflare 外の DNS ゾーンでカスタムドメインを使える点や、Early Hints あたりに限られる。
ランタイム面では、Workers が V8 Isolate 上で動くのでコールドスタートがほぼゼロ^11という特徴がある。V8 Isolate とは Chrome の JavaScript エンジン V8 が提供する軽量な実行コンテキストの単位で、もともとはブラウザがタブごとに JS を隔離するために作られた仕組みだ。OS プロセスや Docker コンテナを起動するのに比べてミリ秒未満で立ち上がるため、AWS Lambda のようなコンテナ型サーバーレスで起きる数百ミリ秒〜数秒の起動遅延が発生しない。代わりにメモリは 1 Isolate あたり 128MB に固定されていて、ここがメモリ重視のワークロードでの天井になる。
さらに fetch() や DB 問い合わせなどの I/O 待ち時間は CPU 時間にカウントされない^12 ので、外部 API を叩く処理は CPU 時間が短く、Free 枠の 10ms 制限内に収まりやすい。
Workers にも Git 連携の CI/CD(Workers Builds)があり、push ごとに wrangler deploy を回せる^13。Pages から移ったとしても CI/CD 体験は維持できる。
Cloudflare エコシステムでどこまで作れるか — 無料枠を一覧する
「Cloudflare = 静的サイトホスティング」というイメージで止まっていると見落とすが、データストア・認証・キュー・AI 推論まで一通り揃っていて、Free 枠でフルスタックアプリが組める。主要サービスの Free 枠を表にする^14。
| サービス | 種類 | Free 枠 | 主なユースケース |
|---|---|---|---|
| Workers | サーバーレスコンピュート | 10万リクエスト/日、10ms CPU/呼出 | API、SSR、ルーティング |
| Pages | 静的ホスティング | 無制限帯域、500ビルド/月 | フロントエンド配信 |
| D1 | SQLite ベース RDB | 500万行読取/日、10万行書込/日、5GB^15 | ユーザーデータ、商品管理 |
| KV | キーバリューストア | 10万読取/日、1,000書込/日、1GB^16 | キャッシュ、セッション、設定値 |
| R2 | S3 互換オブジェクトストレージ | 10GB、100万Class A ops/月、エグレス無料^17 | 画像、ファイルアップロード |
| Durable Objects | ステートフルオブジェクト | 10万リクエスト/日、1GB | リアルタイム通信、WebSocket |
| Browser Rendering | ヘッドレスブラウザ | 10分/日 | OGP 画像生成、スクレイピング |
無料枠で組めるアプリの規模感はざっくりこの程度:
- D1 の 500万行読取/日 は、1ページ表示で平均5クエリ × 各10行読取と仮定して だいたい 1日10万PV相当
- Workers の 10万リクエスト/日 は 静的アセットのリクエストはカウントされないので、API 呼び出しのみが対象
- R2 のエグレス(データ転送)が完全無料なのは大きい。AWS S3 ではここが大きなコスト要因になるため、画像・ファイル配信を伴うアプリではこれだけで採用理由になりうる
認証も自前で組める。Cloudflare 上では Auth.js(NextAuth)が D1 をセッションストレージに使えるチュートリアルが公式にある^18 し、Better Auth に Cloudflare 用統合パッケージを当てる構成も実用段階にある^19。Cloudflare Access(Zero Trust の前段認証)を被せれば社内ツール的な用途も組み立てられる。
「DB がないから静的サイトしかできない」というのは現状ではもう誤解で、認証・DB・ファイルストレージ・リアルタイム通信・AI 推論まで Cloudflare 内で完結する。制約として残るのはメモリ(128MB/Isolate 固定)と D1 の規模(10GB/DB 上限)あたりで、それを超えるなら Hyperdrive 経由で外部 PostgreSQL を繋ぐか、2026年4月 GA の Containers^20 を使う、という代替策がある。
Supabase との比較 — 「非アクティブで止まらない」が効く
これは比較記事のときから気になっていた点だが、Supabase の Free 枠は API リクエストが 7 日間ないとプロジェクトが自動停止 し、90 日放置で永久削除される^21。停止中は DB の読み書きも接続もできず、復旧には手動操作が要る。
Cloudflare には非アクティブ停止がない。Workers / Pages / D1 / KV / R2 のいずれも、リクエストがなくても止まらない。V8 Isolate のおかげでコールドスタートもほぼゼロ^11。
| 項目 | Cloudflare(Free) | Supabase(Free) |
|---|---|---|
| 非アクティブ停止 | なし | 7日で自動停止 |
| データ削除リスク | なし | 停止後 90 日で永久削除 |
| コールドスタート | ほぼゼロ | DB 復旧に数十秒〜数分 |
| DB | D1(5GB、500万行読取/日) | PostgreSQL(500MB、無制限クエリ) |
| ストレージ | R2(10GB、エグレス無料) | 1GB |
| 認証 | Auth.js 等で自前構築 | Auth 組み込み済み |
| リアルタイム | Durable Objects | Realtime 組み込み済み |
Supabase の優位点は 認証・リアルタイム・PostgreSQL が最初から統合されている DX にある。一方で 放置しても止まらない・コールドスタートがない・エグレス無料 という Cloudflare 側の特性は、個人開発・サイドプロジェクトで効きやすい。自分のように「広告付きブログから導線を引いて、アクセスは波があり、放置されている期間もそれなりにある」用途では、停止しないだけで実質的に勝ち、という感覚がある。
料金と制限 — Free と $5/月 の関係
Pages 自体は 全プランで帯域幅・リクエスト・シート数が無制限^22。月額の差は同時ビルド数とビルド回数の差になる。
| 項目 | Free | Pro | Business |
|---|---|---|---|
| 月額 | $0 | $25 | $250 |
| 同時ビルド数 | 1 | 5 | 20 |
| 月間ビルド数 | 500 | 5,000 | 20,000 |
| ファイル数上限/サイト | 20,000 | 100,000 | 100,000 |
| 帯域幅 | 無制限 | 無制限 | 無制限 |
Pages Functions の課金は Workers 側のプランに従う^23。
| 項目 | Free | Paid($5/月〜) |
|---|---|---|
| リクエスト数 | 100,000回/日 | 1,000万回/月含む(超過 $0.30/百万回) |
| CPU 時間 | 10ms/呼出 | 3,000万 CPU ms/月含む(超過 $0.02/百万ms) |
| 帯域幅 | 無制限 | 無制限 |
ポイントは CPU 10ms/呼出は本当に短い ところで、単純な CRUD ならまったく問題ないが、複雑な JSON 加工や画像処理に踏み込むと簡単に超過する。とはいえ I/O 待ちが課金されない設計なので、外部 API を待つだけのワーカーは Free のままでも回る。
ファイルサイズの上限は 25 MiB/アセットで、これを超える素材は R2 にアップロードして公開バケットから配信する設計に倒すのが正攻法^24。ビルドタイムアウトは 20 分。
セキュリティヘッダーはデフォルトで付かない — _headers を自分で書く
地味だが見落としやすい注意点として、Cloudflare Pages はデフォルトではセキュリティ系の HTTP ヘッダーをいっさい送信しない^25。_headers ファイルをビルド出力ディレクトリに置いて自分で定義する必要がある。
/* X-Frame-Options: DENY X-Content-Type-Options: nosniff Referrer-Policy: strict-origin-when-cross-origin Permissions-Policy: camera=(), microphone=(), geolocation=() Strict-Transport-Security: max-age=31536000; includeSubDomains; preload Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'securityheaders.com のような外部スキャナで F 評価が出るのは大抵これが原因。デプロイ前に _headers を必ず一枚噛ませておきたい。
SSL/TLS は管理画面から Full (strict) を選んでおく^26。プレビューデプロイメントを限定公開したい場合は、Cloudflare Access のポリシーをハッシュ付きプレビュー URL(373f31e2.your-app.pages.dev のような形式)に当てる構成にできる。
どう使い分けるか(2026年6月時点)
ここまで踏まえての使い分けの感覚を整理する。
- 既存の Pages プロジェクト: そのまま運用継続でよい。Cloudflare 側で強制移行をかけている話は今のところない
- これから新規でフルスタックを立てる: 素直に Workers を選ぶ。新機能は Workers に先に入るし、Cron / Gradual Deployments / 全バインディングが最初から使える
- これから新規で静的サイト中心(ブログ・ドキュメント): Pages 相当の使い方は Workers の Static Assets 機能 でほぼカバーできる^27。
wrangler.jsoncのassets.directoryを指定するだけで静的配信が成立し、課金体系も Pages 同等 - Cloudflare 外の DNS ゾーンでカスタムドメインを使いたい: ここだけは Pages に優位が残るので、要件に応じて Pages を選ぶ余地はある
このブログ自体は Netlify で動かしているので Pages とは別系統だが、これから自作 Web アプリを置く先としては Workers + Static Assets を第一候補にすることになりそうだ。
まとめ
- 比較で表面の選定をしたあと、採用前に Cloudflare Pages の内部まで踏み込んで調査しておいたメモを、今になって記事化した
- Pages Functions の正体は Workers ランタイムだが、バインディングは Workers のサブセット
- Pages と Workers は収束方向にあり、新規プロジェクトはもう Workers が前提という状況になっている
- 無料枠は D1 / KV / R2 まで揃っていて、認証も Auth.js などで自前構築できる。フルスタックは普通に組める
- 非アクティブ停止がない・コールドスタートがない・R2 エグレス無料、というのが Supabase との大きな差で、放置耐性を求める個人開発に効く
- セキュリティヘッダーはデフォルトでは付かないので
_headersを自分で書く
採用前にここまで見ておけば、後から「思ってたのと違う」が出にくい。比較編とセットで読んで、自分のように選定で迷っている人の役に立てばと思う。
→ 比較編はこちら: Webアプリを無料で公開したいときに使えるホスティングサービスを商用利用と放置耐性で比較してみた
参考文献
- Cloudflare Pages Overview https://developers.cloudflare.com/pages/
- Cloudflare Network Map https://www.cloudflare.com/network/
- Cloudflare Pages vs Vercel vs Netlify (2026) https://hosting-ranked.com/cloudflare-pages-vs-vercel-vs-netlify/
- Pages Functions https://developers.cloudflare.com/pages/functions/
- Direct Upload https://developers.cloudflare.com/pages/get-started/direct-upload
- Pages Functions Bindings https://developers.cloudflare.com/pages/functions/bindings/
- Pages Functions Advanced mode https://developers.cloudflare.com/pages/functions/advanced-mode/
- Bringing a unified developer experience to Cloudflare Workers and Pages https://blog.cloudflare.com/pages-and-workers-are-converging-into-one-experience/
- Migrate from Pages to Workers https://developers.cloudflare.com/workers/static-assets/migration-guides/migrate-from-pages
- Workers vs Pages compatibility matrix https://developers.cloudflare.com/workers/static-assets/compatibility-matrix/
- Eliminating cold starts with Cloudflare Workers https://blog.cloudflare.com/eliminating-cold-starts-with-cloudflare-workers
- Workers pricing — never pay to wait on I/O again https://blog.cloudflare.com/workers-pricing-scale-to-zero
- Workers Builds Git integration https://developers.cloudflare.com/workers/ci-cd/builds/git-integration/
- Cloudflare Developer Platform Pricing https://workers.cloudflare.com/pricing/
- D1 Limits https://developers.cloudflare.com/d1/platform/limits
- KV Pricing https://developers.cloudflare.com/kv/platform/pricing
- R2 Pricing https://developers.cloudflare.com/r2/pricing/
- Auth.js + Next.js + D1 Tutorial https://developers.cloudflare.com/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1/
- better-auth-cloudflare https://github.com/zpg6/better-auth-cloudflare
- Containers and Sandboxes GA https://developers.cloudflare.com/changelog/post/2026-04-13-containers-sandbox-ga/
- Paused Free Plan projects are restorable for 90 days https://supabase.com/changelog/27497-paused-free-plan-projects-are-restorable-for-90-days
- Cloudflare Pages Pricing https://www.cloudflare.com/en-ca/developer-platform/products/pages/
- Workers Pricing https://developers.cloudflare.com/workers/platform/pricing
- Pages Limits https://developers.cloudflare.com/pages/platform/limits
- Cloudflare Pages Security Guide https://zeriflow.com/blog/cloudflare-pages-security-guide
- SSL Full (strict) https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/full-strict
- Workers Static Assets https://developers.cloudflare.com/workers/static-assets/