Back to posts

Cloudflare WorkersとPagesの使い分け:静的で済むか、リクエスト時に処理が要るか

このサイトは、Astroでビルドした静的ブログをCloudflare Pagesで公開する構成です。移行を調べているときに一番引っかかったのが、「PagesとWorkers、結局どっちを使うものなのか」という点でした。名前が並んでいると二者択一に見えるのですが、実際にドキュメントを読むと、関係はもう少し単純です。

結論から書くと、このサイトの判断はこうなっています。

静的ファイルの配信で済む間はPagesのまま。リクエストが来た時点で処理が必要な場所が出てきたら、まずPages Functionsで足りるかを見る。独立したAPIや定期実行のように、サイトの配信と切り離したい処理だけをWorkersに分ける。

まず関係を整理する:FunctionsはWorkersの上で動く

Pagesは、Gitリポジトリとつないでビルドし、生成物をそのまま配信するのが基本の形です。ここに動的な処理を足したいとき使うのがPages Functionsで、プロジェクト内の functions/ ディレクトリにファイルを置くと、そのパスに対応するサーバー側のコードとして動きます。

大事なのは、このFunctionsが「Pages専用の別物」ではないことです。公式ドキュメントにもあるとおり、Pages FunctionsはCloudflare Workersのランタイムの上で実行されます。料金の数え方も同じで、FunctionsへのリクエストはWorkersのリクエストとして数えられます。無料プランでは、FunctionsとWorkersを合わせて1日100,000リクエストが上限で、この枠を両者で共有します(2026年4月時点の公式料金ページで確認)。

一方のWorkersは、もともとサーバー側コードを実行するための土台そのものです。今は静的アセットも一緒に持てるようになったので、「Workersだけでサイト全体を配信する」こともできます。ただ、できることと、このサイトに必要かどうかは別の話です。

比較表:役割の違いだけを見る

細かい制限値ではなく、「何を担当させるものか」で比べるとこうなります。

観点Pages(静的配信)Pages FunctionsWorkers(単体)
主な役割ビルド済みファイルの配信Pagesのサイトに足す動的処理独立したサーバー処理・API
コードの置き場なし(静的ファイルのみ)プロジェクト内の functions/独自のプロジェクトとして管理
実行基盤配信のみでコードは動かないWorkersランタイムWorkersランタイム
課金の数え方静的リクエストは無料・無制限Workersのリクエストとして計上Workersのリクエストとして計上
状態の持ち方持てないKVやD1などをバインディングして参照できるKV、D1、Durable Objectsなど幅広い
向いているものブログ、ドキュメント、コーポレートサイトフォーム受付、認証、軽いAPI追加定期実行、独立API、複数サイト共通の処理

静的リクエストが無料・無制限というのは、PagesでもWorkersの静的アセットでも共通です。つまり「アクセスが増えたらWorkersにしないと」という理由では、判断は動きません。分かれ目は料金ではなく、処理の置き場です。

判断フロー:3つの問いだけでだいたい決まる

自分のサイトで迷ったときは、次の順に考えることにしています。

  1. ビルド時に決着がつくか。 記事一覧、RSS、サイトマップ、OGP画像の生成などは、Astroのビルドで作って静的ファイルとして置けます。これで済むなら、配信時にコードを動かす理由がありません。Pagesの静的配信で終わりです。
  2. リクエストが来ないと決まらない処理か。 訪問者ごとに結果が変わる、外部のAPIをその場で叩く、送られてきた内容を受け取る——この類は配信時処理が必要です。ただし、対象がこのサイト内の特定パスだけなら、Pages Functionsを1ファイル置くのが一番小さい構成です。
  3. 状態を持ち続けるか、サイトと独立しているか。 カウンタや申請データのように書き込みが積み上がるもの、決まった時刻に走る定期処理、他のサイトからも使うAPIは、サイトの配信と一緒にしておく必然性が薄くなります。ここまで来たらWorkersとして分ける方が、後から触るときに見通しがよくなります。

判断の物差しは「高機能な方を選ぶ」ではなく、「その処理は誰の都合で、いつ動くのか」です。ビルド時で済むものをわざわざリクエスト時に動かすと、障害点と課金対象が増えるだけでした。

もう1つ、Functionsには実務的な注意点があります。Functionsを追加すると、初期状態では全リクエストがFunctionを経由する扱いになるため、静的ファイルまで枠を消費しかねません。公式ドキュメントでは _routes.json で対象ルートを絞る方法が案内されていて、静的配信の「無料・無制限」を保つにはこの設定が効きます。小さい処理のつもりで全体に被せない、というのはFunctionsを使う側の作法です。

個人ブログで出番になる例、ならない例

具体例で見ると、線引きはかなりはっきりします。

やりたいこと置き場理由
記事ページや一覧の表示Pages(静的)ビルドで生成でき、訪問者ごとに変わらない
旧URLからの細かいリダイレクトまずPagesの _redirects、条件分岐が必要ならFunctions/Workers単純な転送は静的設定で足りる。User-AgentやCookieで分けるような条件が付くとコードの仕事になる
お問い合わせフォームの受付Pages Functions送信内容を受けて外部サービスへ渡すだけなら、サイト内に小さく収まる(APIキーなど秘密情報の扱いはPages/Workersの環境変数と秘密情報の扱いにまとめています)
下書きプレビューへの簡易アクセス制限Pages Functions(ミドルウェア)特定パスだけ認証をかけたい、という形はFunctionsの得意な範囲
記事ごとの閲覧数カウンタWorkers+KV/D1書き込みと集計という「状態」が主役になるため
外部サービスの新着を定期取得して表示に使うWorkers(Cron Triggers)訪問者のリクエストとは無関係に時刻で動く処理は、サイト配信と切り離した方が素直

逆に、このブログでは当面出番が来なさそうなものもあります。コメント欄は付けていないので、その受付や保存は不要です。本文検索もPagefindで静的に済ませています。「ブログなら普通はあるはず」という理由だけで動的機能を足すと、守るもの(データ、認証、スパム対策)が先に増えます。出番は、必要になったときに初めて来るものとして扱っています。

Workers単体まで行くのはどんなときか

公式にはPagesからWorkersへの移行ガイドも用意されていて、Durable ObjectsやCron Triggers、より細かい観測まわりなど、Workersの方が機能の範囲は広いと説明されています。新規に何でも入る箱が欲しいならWorkersから始める、という今のCloudflareの推奨も理解はできます。

それでもこのサイトをPagesに置いているのは、理由が「静的ブログだから」で十分だからです。配信するファイルが先にあって、コードは添え物。その主従が逆転する日——たとえば会員向けの内容を始めたり、APIを他所へ提供したりするようになったら、その時点で分け方を見直せばいいと考えています。移行ガイドがあるということは、後から移る道も残されている、ということでもあります。

参考