Firebaseに支出上限が来た — spend capsが止められるもの、止められないもの

はじめに

Blaze プラン(従量課金)に上げた瞬間から、Firebase には「上限がない」という一点だけがずっと残り続けていた。予算アラートはメールを送るだけで課金は止まらず、本当に止めたければ請求先アカウントをプロジェクトから外す——つまりプロジェクトごと落とす——しかなかった。r/Firebase で何年も繰り返されてきた「寝る前は $5、起きたら $50,000」という類の投稿は、この構造がそのまま表に出たものだ。

2026年9月14日、Firebase はここに spend caps(支出上限) を入れた。特定のサービスだけを、予算に達した時点で自動的に一時停止する。Public Preview での提供で、9月17〜18日にかけて r/FlutterDev と r/Firebase の両方に公式アナウンスが投稿され、Flutter 側からの反応が大きい。

この記事では、spend caps が具体的に何を止めるのか、従来の手段とどう違うのか、そして公式が繰り返し書いている「これはハードキャップではない」という但し書きが実務上どこまで効くのかを整理する。

入ったのは「サービス単位の一時停止」

まず対象範囲を正確に押さえておきたい。公式ドキュメントが挙げているのは4つだ。

  • Firebase AI Logic(Gemini Developer API / Agent Platform Gemini API)
  • Cloud Functions for Firebase(実体は Cloud Run functions)
  • Firebase App Hosting(実体は Cloud Run)
  • Firebase Extensions(実体は Cloud Run functions)

発表ブログは前者3つを挙げているが、ドキュメント側は Extensions を含めた4サービスを列挙している。共通点は明快で、いずれも下回りが Cloud Run(またはそのバリアント)であること。つまり今回の spend caps は「Firebase 全体の支出上限」ではなく、Cloud Run 系のコンピュート課金に対する遮断器として設計されている。

設定は Firebase コンソールの Settings > Usage and billing > Details & settings にある「Service-level spend caps」カードから、サービスごとに月額の予算を入れるだけ。予算期間は暦月固定で、毎月1日にリセットされる。通知は 50% / 80% / 100% の3段階でメールが飛び、100% に達すると当該サービスがその月の残り期間、新規の利用を止める。

設定には Billing Account Administrator か Project Owner、あるいは Billing Account Costs Manager + Project Editor の組み合わせが要る。開発者が勝手に設定できる類のものではなく、請求側の権限を持つ人間が押さえる位置づけだ。

停止が解除されるパスは2つある。翌月1日に自動で解除されるか、Cloud コンソールから手動で上限を引き上げるか。手動解除の場合、サービスが完全に復帰するまで最大1時間かかるとドキュメントは明記している。障害対応中にこれを踏むと、体感はかなり重い。

従来手段との差 — アラートは止まらず、キルスイッチは効きすぎた

spend caps の位置づけは、既存の2つの手段の間を埋めるものとして見ると理解しやすい。

予算アラートキルスイッチ(請求無効化)spend caps
実際に止まるか止まらない(通知のみ)止まる止まる
停止の粒度—プロジェクト全体サービス単位
データへの影響なしデータ損失の可能性ありなし
構築コスト低Pub/Sub + Cloud Function + Billing APIコンソールで数値を入れるだけ
復帰—手動再有効化、サービスの原状復帰は無保証翌月自動 or 手動(最大1時間)

予算アラートは、設計上そもそも止める機能を持っていない。 メールが届いた時点で再帰ループが回っていれば、読んで対処するまでの時間はそのまま課金され続ける。

キルスイッチ——Cloud Billing の予算通知を Pub/Sub トピックに流し、Cloud Function が Billing API を叩いてプロジェクトから請求先アカウントを外す構成——は、長らく「本気で止めたいならこれ」として共有されてきた。Google 自身も「予算通知を使ってプログラム的に Cloud Billing を無効化する」手順を公開している。ただしこれはプロジェクト内の全 Google Cloud サービスを終了させる操作で、公式ドキュメントは請求を無効化するとデータが失われる可能性があり、再有効化しても全サービスが元通りになる保証はないと警告している。暴走する Cloud Function 1本を止めるために、Firestore ごと道連れにする構成だったわけだ。

spend caps は、この「粒度が粗すぎる問題」を正面から解いている。AI Logic の予算が尽きても Firestore は生き続けるし、Functions が止まっても Authentication は動く。アプリが全損するのではなく、該当機能だけが壊れる。

同種の仕組みは他プラットフォームにもある。Vercel の Spend Management は、設定額に達したときにチーム内全プロジェクトの本番デプロイを一時停止するオプションを持つ(訪問者には 503 DEPLOYMENT_PAUSED が返る)。ただし停止は即時ではなく、Vercel 側のチェックが数分おきであるため「上限を超えてから数分はトラフィックを捌き、課金も進む」と明記されている。さらに解除はプロジェクト単位の手動操作で、上限額を上げても自動では再開しない。

Firebase の spend caps と Vercel を並べると、遅延を許容せざるを得ない点は共通で、止める粒度が違う。Vercel は「チーム全体か、何もしないか」、Firebase は「サービス単位」だ。

「ハードキャップではない」の中身

ドキュメントは spend caps が hard cap ではないことを何度も繰り返す。中身は3つある。

1つ目は反映の遅延だ。 利用量のレポーティングにラグがあるため、上限の適用は即時ではなく数分遅れる。この数分の間に発生した超過分は、通常どおり課金される。再帰トリガーのような、1秒あたりの発火数が指数的に伸びるパターンでは、この数分がそのまま損害になる。公式が「絶対に許容できる額より少し低めに設定せよ」と書いているのはこのためだ。

2つ目は計算基準だ。 spend caps の計算には**グロスコスト(割引・クレジット・無料枠適用前)**が使われる。無料枠の範囲内で回っているつもりでも、グロスでは計上が進む。クレジットを大量に持っているプロジェクトほど、体感と乖離する。

3つ目は、停止がアプリ側にどう見えるかだ。 ドキュメントは端的に書いている——上限が適用されると、クライアントアプリは該当サービスに対してエラーを投げ始める。つまり spend caps は「安全に縮退する」機能ではなく、「指定したサービスを落とす」機能である。AI Logic に上限を設けるなら、Gemini 呼び出しが失敗したときに何を表示するかを先に決めておかないと、月末にユーザーから見えるのは無言のクラッシュになる。ここは実装側の宿題として明確に残る。

対象外に残るもの — Firestore は止まらない

実務上いちばん重要なのは、この4サービス以外は対象外という点だ。Cloud Firestore、Realtime Database、Cloud Storage、Authentication、Hosting には spend cap を設定できない。使えるのは従来どおりアラートのみの予算だけである。

冒頭に挙げた「寝て起きたら $50,000」の古典的な事故は、Firestore の onWrite で発火した関数が同じドキュメントに書き戻して無限に再帰するパターンだった。この構成で発生するコストは、Functions の起動料金と Firestore の読み書き料金の両方に乗る。spend caps が押さえるのは前者だけだ。

したがって現実的な組み方は、spend caps を単体の解決策として置くのではなく、既存の防御と重ねることになる。

  1. maxInstances で並列度を縛る。 公式ドキュメントはこの設定を「コストを制御する、あるいはバックエンドサービスへの接続数を制限する方法」として明示している。2nd gen SDK なら setGlobalOptions({ maxInstances: 10 }) で全関数に既定値を入れ、必要な関数だけ個別に上書きできる。同時実行数を縛るのは、レポーティング遅延の影響を受けない点で spend caps と性質が違う。ただし低く設定しすぎると上限到達時にリクエストがドロップされうる、とドキュメントは注意している。
  2. spend caps を Cloud Run 系4サービスに敷く。 特に AI Logic は、トークン単価 × 呼び出し回数が読みにくい筆頭で、今回いちばん恩恵が大きい。
  3. Firestore / Storage にはアラートのみの予算を置き続ける。 ここは依然として自動停止の手段がない。
  4. 再帰トリガーそのものを設計で殺す。 書き戻し先を別コレクションにする、更新前後を比較して no-op なら early return する、といった従来の作法は何も変わっていない。

spend caps は最後の防波堤であって、堤防そのものではない。

まとめ

  • Firebase が AI Logic / Cloud Functions / App Hosting / Extensions の4サービスに、サービス単位の支出上限を導入した(2026年9月14日、Public Preview)。
  • 予算は暦月単位、通知は 50/80/100%、100% で当該サービスがその月いっぱい停止する。翌月1日に自動解除、手動解除は復帰まで最大1時間。
  • 従来の「アラートは止まらない / キルスイッチはプロジェクトごと落としてデータ損失のリスクがある」という二択の中間が、ようやく埋まった。
  • ただしハードキャップではない。反映は数分遅れ、計算はグロスコスト、停止するとクライアントはエラーを受け取る。
  • Firestore / RTDB / Storage は対象外。古典的な再帰トリガー事故のコストは半分しか止まらない。

Cloud Run 系から入れたということは、下回りが Cloud Run に寄っている Firebase プロダクトから順に広がる余地があるということでもある。Firestore のような自前の課金体系を持つサービスにまで届くかどうかが、この機能が「AI 時代の応急処置」で終わるか「Blaze の設計思想の変更」になるかの分かれ目になる。

今日のその他のニュース

Supabase Realtime Broadcast がバイナリペイロードに対応。 WebSocket・REST API・DB 経由で bytea を直接送受信できるようになった。センサーストリームや画像フレームを Base64 で包んで JSON に載せていた構成では、オーバーヘッドがそのまま消える。(Supabase Changelog)

Apple XNU の IPC Panic。 2行の順序が逆だったために、4つの Mach 呼び出しで macOS / iOS を長年リブートさせられた脆弱性の解析記事。権限昇格ではなく可用性の話だが、再現手順の短さが目を引く。(r/programming)

Google Play のアプリ審査が長期化している。 審査待ち時間が伸びており、クローズドテスト要件と合わせてリリースまでの所要日数が読みにくくなっている。リリース計画にバッファを積む必要がある。(GIGAZINE)

ソース