Vercel CDNでFastAPIの静的ファイル配信を効率化する

Vercel CDNがFastAPIのapp.frontend()とStaticFilesを直接配信し、Function呼び出し、CPU、オリジン転送を減らす仕組みを解説します。料金への影響、ルート順序、ミドルウェア、依存関係の注意点を押さえ、公開ファイルと保護ファイルを分けて安全に検証する手順まで整理しました。

Sunday, September 13, 2026Omid Saffari
Tools
Vercel CDNでFastAPIの静的ファイル配信を効率化する

2026年9月10日、VercelはFastAPIアプリのコスト構造をひとつ変えました。対象となるフロントエンドと静的ファイルのリクエストは、Vercel CDNから訪問者へ直接配信されるようになり、Function Invocationsとコンピュート使用量を発生させなくなりました。ただし、CDN Requestsと転送量は引き続き発生します。つまり、静的配信が無料になるのではなく、Function利用が減る変更です。

Vercel CDNがFunctionを迂回する仕組み

静的ファイルとは、HTMLファイル、スタイルシート、JavaScriptバンドル、フォント、画像など、サーバーがそのまま返せるファイルです。Vercel Functionは、動的リクエストを処理する実行中のFastAPIプロセスを指します。CDNは、訪問者の近くでコンテンツを届ける配信レイヤーです。

この変更以前は、FastAPI経由でマウントしたファイルもFunctionの経路を通る場合がありました。リクエストはVercelのネットワークに届いた後、FastAPI Functionを呼び出し、Pythonがファイルを返していました。

現在はビルド時に、app.frontend()とFastAPIのStaticFiles配下から対象ファイルをVercelが検出します。該当ファイルはCDNへ昇格され、一致するリクエストはFunctionを呼び出さずに配信されます。

リクエストの経路は、次の状態から

visitor → CDN → FastAPI Function → file → visitor

次のように変わります。

visitor → CDN file → visitor

動的APIまで静的になるわけではありません。移動するのは、条件に一致するファイルだけです。プロジェクト直下のpublic/ディレクトリにあるファイルは以前からCDNで配信されていたため、公開アセットをすべてそこに置いているアプリでは、このリリースによる新たな削減効果はありません。

CDNへ昇格したディレクトリも、デフォルトではFunctionバンドル内に残ります。tool.vercel.fastapi.static.exclude = trueを設定すれば重複したコピーを削除できますが、これは別のバンドル設計上の判断です。CDN経由のリクエストを有効にするために、この設定は必要ありません。

公開FastAPIアセットが訪問者からCDNまでの短い経路を通り、保護対象アセットはガードを備えたFunctionを通る構成を示す断面図
公開アセットはCDNで配信を完結できます。FastAPIによるリクエスト確認が必要な保護対象アセットは、引き続きFunctionを経由します。

減るのはコンピュート料金で、配信料金ではありません

Vercelは、ひとつのリクエストを複数のレイヤーで計測します。Function Invocationsはコードまで到達したリクエスト数です。Active CPUとProvisioned Memoryは、呼び出しの処理量と実行時リソースを表します。Fast Origin Transferは、CDNとFunctionの間で発生する通信量です。

一方、外側の配信メーターは別に計測されます。ダッシュボードでEdge Requestsと表示されるCDN Requestsは、静的アセットとFunctionトラフィックの両方が対象です。Fast Data Transferは、CDNから訪問者へ送ったバイト数を計測します。

デプロイ前はFunctionに到達し、デプロイ後は昇格の対象になる、条件が同じ100万件のアセットリクエストを整理すると次のようになります。

メーター昇格前昇格後
Function Invocations100万0
対象リクエストのActive CPU計測対象0
対象リクエストのProvisioned Memory計測対象0
対象レスポンスのFast Origin Transfer計測対象0
CDN RequestsまたはEdge Requests100万100万
訪問者へのFast Data Transfer転送バイトを計測転送バイトを計測

Proで公表されている料金は、Function呼び出し100万回あたり$0.60です。したがって、従来Functionまで届いていたファイルリクエスト100万件を移せば、月次クレジット適用前のFunction Invocations利用額が$0.60減ります。さらに、実際に消費していたActive CPU、Provisioned Memory、Fast Origin Transferも削減対象になります。

後半の削減量は、各プロジェクトのUsageデータで確認する必要があります。Pythonをほとんど動かさずに返していたファイルなら、減らせるCPUはわずかです。大きなレスポンスなら、削減できるオリジン転送量も増える可能性があります。このリリースが提供するのは新しい配信経路であり、一律の削減率ではありません。

CDN利用量は、別のコスト項目として残ります。Vercelの現行CDN料金ページでは、オンデマンド課金のProに最初の1,000万件のEdge Requestsと最初の1 TBのFast Data Transferが含まれ、その後はリージョン別の利用料金が適用されます。Flat Rate CDNを使うチームは、そのプランに設定されたリクエスト数と転送量の枠を消費します。この別枠の予算判断については、Flat Rate CDNの解説で詳しく扱っています。

Hobbyでは、現金支出が減る代わりに利用枠へ余裕が生まれる場合があります。HobbyにはFunction Invocations 100万回、Active CPU 4時間、Provisioned Memory 360 GB-hoursが含まれます。Functionに届かなくなった公開ファイルのトラフィックは、これらの枠を消費しません。ただし、CDN配信は該当するメーターに引き続き計上されます。

対象になるかはルートとセキュリティ設定で決まります

StaticFilesについて、VercelはFastAPIの宣言順序を維持します。静的マウントより前に宣言されたルートが同じパスにあれば、そのルートが優先されてFunctionへ到達します。マウントより後に宣言されたルートは、CDN上のファイルに優先されません。

app.frontend()の挙動は少し異なります。宣言順序にかかわらず、APIルートは常にフロントエンドファイルより優先されます。そのため、/にフロントエンドをマウントしても、実際のAPIエンドポイントが奪われることはありません。

セキュリティ設定によってもデフォルト動作は変わります。CDN上のファイルはPythonを通らないため、FastAPIのミドルウェアやDepends()によるチェックを実行できません。このためVercelは、次のパスをデフォルトでFunction側に残します。

  • アプリにトップレベルのミドルウェアがある場合、そのアプリのすべての静的マウントとフロントエンド。
  • サブアプリにミドルウェアがある場合、そのサブアプリの静的マウント。
  • FastAPIの依存関係で保護されたフロントエンド。

cdn = falseは反対の選択です。昇格を無効にして、一致するすべてのリクエストをFunction側に残します。アプリケーションコードでリクエストごとの確認が必要なら、妥当な判断です。

小さなエッジケースもあります。StaticFilesをマウントしたルートそのものへのリクエストは、末尾にスラッシュを付けた形式へFastAPIがリダイレクトするため、引き続きFunctionに到達します。そのパスをクライアントが繰り返し要求する場合、Function利用量が完全なゼロになるとは考えないでください。

実務への影響

FastAPIリポジトリをひとりで運営するSaaS創業者

app.frontend()でバンドル済みWebアプリを配信している創業者なら、APIは動的なまま維持しつつ、公開HTML、CSS、JavaScriptのトラフィックをFunctionの経路から外せます。得られるのは、コンピュート利用の基準線が明確になることです。プロダクトのトラフィックが増えても、ブラウザによるアセット取得のたびにバックエンド処理として計上されなくなります。

公開ファイルと顧客限定ファイルを扱う制作会社のエンジニア

制作会社のエンジニアは、公開シェルをCDNに置きながら、機密性のあるルートを静的マウントより前に宣言できます。利点はFunction利用の削減だけではありません。どの顧客ファイルにPythonでのアクセス判定が必要で、どれには不要なのかをルート構成そのものが示すようになります。

財務部門と連携するバックエンド責任者

バックエンド責任者は、Function項目には動的なFastAPIトラフィック、CDN項目には訪問者向けの全トラフィックという形で、別々の予測を財務部門へ提示できます。これにより、Function Invocationsの減少をEdge Requestsや転送量も同じだけ減るものと誤解せずに済みます。

グローバルミドルウェアを使うチーム

トップレベルでロギング、テナント判定、認証のミドルウェアを使うチームでは、静的マウントがデフォルトでFunction側に残ると考えるべきです。実務上の検討事項は、明確に公開できるアセット領域だけがそのミドルウェアを迂回してよいかどうかです。認められないなら、この変更を根拠に安全な削減額を見込むことはできません。

ひとつのデプロイを監査する

拡張子があるファイルはすべて公開用だと決めつけず、実際のルート一覧から始めます。

  1. 公開パスと保護対象パスを分類する

    すべてのapp.frontend()ディレクトリとStaticFilesマウントを一覧にします。誰にでも返せるファイルを公開用として分類してください。ユーザー、テナント、ロール、Cookie、またはリクエスト時のミドルウェアの判定結果によってレスポンスが変わるものは、別に保護対象として分類します。

  2. 宣言順序を確認する

    StaticFilesマウントより優先すべきFunctionルートは、マウントより前に置きます。Vercelのドキュメントにあるパターンは次のとおりです。

    Python
    from fastapi import FastAPI
    from fastapi.staticfiles import StaticFiles
    
    app = FastAPI()
    
    # Declared before the mount, so this route wins over any CDN file at this path.
    @app.get("/static/protected.json")
    def protected():
        return {"access": "denied"}
    
    app.mount("/static", StaticFiles(directory="static"))
  3. 保護対象パスをFunction側に残す

    設定を変える前に、トップレベルのミドルウェア、サブアプリのミドルウェア、フロントエンドの依存関係を確認します。グラフ上の数値を下げるためだけにcdn = trueを設定してはいけません。影響するすべてのファイルが本当に公開用であることが条件です。一致する全トラフィックをFastAPIで処理する必要がある場合は、cdn = falseを使います。

  4. バンドルを縮小するか決める

    実行中のアプリが昇格済みファイルを読み込まないなら、ドキュメントに記載された次の設定で、元のディレクトリをFunctionバンドルから除外できます。

    TOML
    [tool.vercel.fastapi.static]
    exclude = true

    実行時のコードがそのファイルを引き続き必要とする場合は、デフォルト設定のままにします。

  5. デプロイして経路分離を検証する

    vc deployを実行します。公開ファイル、保護対象ファイル、APIルートをそれぞれひとつずつ呼び出してください。保護対象のレスポンスが正しく動作することを確認したうえで、プロジェクトのUsageにあるFunction Invocations、Active CPU、Provisioned Memory、Fast Origin Transfer、Edge Requests、Fast Data Transferを比較します。公開サンプルはCDNの集計から消えず、Functionの経路だけを外れているはずです。

削減効果を過大評価しない

ProのFunction呼び出し単価は100万回あたり$0.60にすぎません。小規模なアプリでは、現金支出の削減が数セントにとどまるか、月次利用クレジットの範囲内に収まる場合があります。より大きな利点は、Function利用量からアセットのノイズを取り除き、本来のAPI処理に使えるコンピュート枠を確保できることかもしれません。

公開アセットのトラフィックが多い場合、従来のFunction経路でメモリ保持時間が無視できないほど長かった場合、またはレスポンスが相応のFast Origin Transferを発生させていた場合は、削減効果が大きくなります。一方、ファイルがすでにpublic/にあった場合、トラフィックが少ない場合、セキュリティ規則によって正しくFunction側に残る場合は、効果も小さくなります。

この変更は、アセット最適化の代わりにはなりません。同じサイズの大きなJavaScriptバンドル、画像、フォントは、引き続きCDNから訪問者へ転送する必要があります。Fast Data Transferを減らすには、それらのファイル自体を小さくする取り組みが有効です。

月曜日に着手すべきこと

app.frontend()またはStaticFilesが公開ファイルを配信しており、そのリクエストがFunction利用量に現れているなら、今週対応する価値があります。ファイルが保護対象で、アクセス規則をまだ切り分けていないなら待つべきです。対象ファイルがすでにpublic/や別のCDN対応パスから配信されている場合、この変更の影響はありません。

月曜日には、公開アセットと保護対象アセットのパスを棚卸しし、実行が必要なルートとガードをすべて維持したうえで、各クラスからひとつずつリクエストしてデプロイを検証します。予算に反映するのは、実測したFunction利用量の減少です。CDN Requestsと転送量は、引き続き別の項目として残してください。

運用コストに影響するプラットフォーム変更を平易に読み解く記事を今後も受け取りたい方は、ニュースレターにご登録ください。

最終更新
2026年9月13日
カテゴリー
Explained

Googleでこのサイトを優先する

omidsaffari.comをGoogle検索の優先ソースに追加

omidsaffari.comを優先ソースに設定すると、GoogleがTop Stories・AI Overviews・AI Modeであなたのために優先表示します。

AI 文字起こしの料金は据え置き:Grok Voice Transcribe 2.0移行ガイド

AI 文字起こしの料金は据え置き:Grok Voice Transcribe 2.0移行ガイド

Grok Voice Transcribe 2.0のAI 文字起こし料金は、バッチが音声1時間あたり$0.10、ストリーミングが$0.20のままです。デフォルトモデル変更で起こり得る出力差、移行前に確認すべき総コスト、1.0と2.0を同条件で検証して本番モデルを固定する手順を、運用担当者向けに整理します。2026年9月20日Explained
HAR ファイルで原因を追う:Cloudflare Browser Runの失敗調査

HAR ファイルで原因を追う:Cloudflare Browser Runの失敗調査

Cloudflare Browser RunのSession RecordingにInspectパネルが加わり、完了後のログ、通信、最終DOMを確認できるようになりました。HAR ファイルで失敗原因を絞り込み、不要な再実行を減らす手順、料金への影響、録画では見えない領域まで、実務向けに分かりやすく解説します。2026年9月19日Explained
v0でnpm プライベートパッケージを活用する:社内コンポーネント再利用の実践ガイド

v0でnpm プライベートパッケージを活用する:社内コンポーネント再利用の実践ガイド

v0が共有環境変数経由でnpm プライベートパッケージに対応。NPM_TOKENとNPM_RCの選び方、認証情報をモデルやSandboxに渡さない仕組み、社内コンポーネントを試作から本番へ引き継ぐ設定手順、料金と実務上の注意点を整理し、差し替え工数を減らせるか判断する方法を解説します。2026年9月19日Explained
Claude Code 料金を見直す:auto modeの分類器課金が消える条件

Claude Code 料金を見直す:auto modeの分類器課金が消える条件

Claude Code 2.1.278では、auto modeの安全判定をサーバー側で処理できるセッションの分類器リクエスト課金がなくなります。API、Enterprise、クラウド、ゲートウェイ環境で適用条件を見極め、/statusで実際の課金経路を確認し、予算へ正しく反映する方法を解説します。2026年9月19日Explained
Vercel ビルド高速化:Turboを1回だけ使う方法と料金

Vercel ビルド高速化:Turboを1回だけ使う方法と料金

VercelのPro/Enterpriseで、プロジェクト設定を変えずに1回のデプロイだけTurboを指定する方法を解説します。GitHubのコミットマーカー、Vercel CLI、デプロイAPIという3つの経路と、1分あたり$0.105からの料金、権限不足時のフォールバック、通常ビルドとの比較手順まで整理しました。2026年9月18日Explained
ChatGPT Word連携の実力:できること・料金・導入手順

ChatGPT Word連携の実力:できること・料金・導入手順

ChatGPT Word連携を使えば、Wordのサイドバーで下書き、要約、選択範囲の修正、見出し調整まで完結します。利用条件、共有される使用量、料金の考え方、データ境界、導入手順を、提案書やSOPの具体例とともに解説。コピペ往復を減らしつつ、事実や約束を守るレビュー方法も紹介します。2026年9月18日Explained
Google Antigravity移行ガイド:10月5日までのローカルジョブ対応

Google Antigravity移行ガイド:10月5日までのローカルジョブ対応

Google Antigravityの5月版エージェントは2026年10月5日に停止予定です。出力のみのジョブはID変更で済みますが、ローカルツールやfunction_callを扱う環境には、新しいツール名、PascalCase引数、行範囲編集に対応するアダプター改修が必要です。安全な移行手順を解説します。2026年9月18日Explained
Cloudflare WorkersのRPCトレースで遅延箇所を特定する

Cloudflare WorkersのRPCトレースで遅延箇所を特定する

Cloudflare WorkersのRPCトレースで、遅い顧客リクエストを別のWorkerやDurable Objectまで追跡。担当サービスとメソッドを見つける手順、サンプリング率、保持期間、2026年10月1日以降のスパン単位の料金まで、チェックアウトの例で実践的に解説します。2026年9月17日Explained
ニュースレター

毎週日曜、一通の手紙。動くシステムの話。感想戦ではなく。

週刊。スパムなし。いつでも解除できます。