Firebase Blaze plan has no hard spending cap, so overbilling prevention is entirely your responsibility. Set up budget alerts in Google Cloud Console to get notifications at spending thresholds. Prevent infinite Cloud Function loops with guard fields, optimize Firestore reads with pagination and caching, and monitor usage in the Firebase Console daily. Budget alerts only send notifications — they do not stop charges. For critical protection, consider programmatic billing controls that disable services when budgets are exceeded.
Preventing Unexpected Firebase Bills on the Blaze Plan
Firebase's Blaze plan charges for usage beyond the free tier with no hard spending cap. Real incidents include bills of $70,000 in a single day from runaway Cloud Functions. This tutorial covers the essential safeguards: budget alerts, function loop prevention, Firestore cost optimization, usage monitoring, and programmatic controls. Every Firebase project on Blaze should implement these protections before going to production.
Prerequisites
- A Firebase project on the Blaze (pay-as-you-go) plan
- Access to the Google Cloud Console (linked to your Firebase project)
- Basic understanding of Firestore pricing (per-read, per-write, per-delete)
- Firebase CLI installed for deploying function safeguards
Step-by-step guide
Set up budget alerts in Google Cloud Console
Set up budget alerts in Google Cloud Console
Go to the Google Cloud Console at console.cloud.google.com and navigate to Billing > Budgets & alerts. Click Create budget, select your Firebase project, and set a monthly budget amount. Add alert thresholds at 50%, 80%, and 100% of your budget. Configure email notifications to go to your team's billing email. Remember: these alerts only send notifications. They do not cap or stop usage.
1// Navigate to: console.cloud.google.com > Billing > Budgets & alerts2// Click: Create budget3// Settings:4// Budget name: Firebase Production5// Projects: your-firebase-project6// Budget amount: $50 (or your expected monthly spend)7// Alert thresholds: 50%, 80%, 100%, 150%8// Notifications: your-team@company.comExpected result: You receive email alerts when your Firebase project reaches each spending threshold.
Prevent infinite Cloud Function loops
Prevent infinite Cloud Function loops
The most common cause of massive Firebase bills is a Cloud Function that writes to the same Firestore collection it triggers on, creating an infinite loop. A single function bug can generate thousands of dollars in charges within minutes. Always add a guard field to prevent re-triggering, and check it at the top of every Firestore trigger handler.
1import { onDocumentCreated } from "firebase-functions/v2/firestore";2import { logger } from "firebase-functions";34// DANGEROUS — this creates an infinite loop:5// export const bad = onDocumentCreated("orders/{id}", async (event) => {6// await event.data.ref.update({ processed: true }); // triggers itself!7// });89// SAFE — guard field prevents re-triggering:10export const processOrder = onDocumentCreated(11 "orders/{orderId}",12 async (event) => {13 if (!event.data) return;14 const data = event.data.data();1516 // Guard: skip if already processed17 if (data.processedByFunction === true) {18 return;19 }2021 await event.data.ref.update({22 processedByFunction: true,23 totalWithTax: data.subtotal * 1.1,24 });2526 logger.info(`Processed order ${event.params.orderId}`);27 }28);Expected result: Cloud Functions include guard fields that prevent infinite re-triggering and runaway billing.
Optimize Firestore reads to reduce costs
Optimize Firestore reads to reduce costs
Firestore charges per document read ($0.06 per 100,000 reads). The most common cost drivers are: reading entire collections instead of paginating, not using caching, and real-time listeners on large collections. Implement pagination with limit(), use aggregate queries for counts, and cache frequently accessed data.
1import { db } from "@/lib/firebase";2import {3 collection, query, orderBy, limit, startAfter,4 getCountFromServer, getDocs5} from "firebase/firestore";67// BAD: Reading all documents (could be thousands of reads)8// const allDocs = await getDocs(collection(db, "products"));910// GOOD: Paginate with limit11async function getProducts(pageSize = 25, lastDoc?: any) {12 let q = query(13 collection(db, "products"),14 orderBy("createdAt", "desc"),15 limit(pageSize)16 );1718 if (lastDoc) {19 q = query(q, startAfter(lastDoc));20 }2122 return getDocs(q);23}2425// GOOD: Use aggregate queries instead of reading all docs to count26async function getProductCount() {27 const snapshot = await getCountFromServer(28 collection(db, "products")29 );30 return snapshot.data().count; // 1 read instead of N reads31}Expected result: Firestore reads are minimized through pagination and aggregate queries, reducing costs significantly.
Set minInstances wisely to control Cloud Functions costs
Set minInstances wisely to control Cloud Functions costs
The minInstances option keeps function instances warm to eliminate cold starts, but each warm instance costs approximately $3-8 per month. Only set minInstances for user-facing HTTP functions where cold start latency matters. Event-driven triggers (Firestore, Auth) can tolerate cold starts since users do not wait for them directly.
1import { onRequest } from "firebase-functions/v2/https";2import { onDocumentCreated } from "firebase-functions/v2/firestore";34// User-facing API — worth keeping warm5export const api = onRequest(6 {7 minInstances: 1, // ~$3-8/mo, eliminates cold starts8 maxInstances: 10, // Cap maximum concurrent instances9 },10 async (req, res) => {11 res.json({ status: "ok" });12 }13);1415// Background trigger — cold start is acceptable16export const onOrder = onDocumentCreated(17 {18 document: "orders/{orderId}",19 // No minInstances — saves money20 maxInstances: 5, // Still cap max to prevent runaway scaling21 },22 async (event) => {23 // process order24 }25);Expected result: Functions have appropriate minInstances and maxInstances settings that balance cost with performance.
Monitor usage in the Firebase Console daily
Monitor usage in the Firebase Console daily
Check the Firebase Console Usage & billing section regularly. The Usage tab shows Firestore reads/writes/deletes, Cloud Functions invocations, Storage bandwidth, and Hosting bandwidth. Look for unexpected spikes that indicate bugs or abuse. Set a calendar reminder to check usage daily during the first month after launching.
1// Navigate to: Firebase Console > your project > Usage & billing2// Key metrics to monitor:3// Firestore: reads/day, writes/day, storage4// Cloud Functions: invocations/day, compute time5// Storage: bandwidth, stored data6// Hosting: bandwidth78// For programmatic monitoring, use the Cloud Monitoring API:9// console.cloud.google.com > Monitoring > DashboardsExpected result: You have a routine for checking Firebase usage and can spot billing anomalies before they become expensive.
Set up programmatic billing safeguards
Set up programmatic billing safeguards
For additional protection, create a Cloud Function triggered by budget alert Pub/Sub notifications that automatically disables billing or scales down services when a budget threshold is exceeded. Google Cloud publishes a reference architecture for this. The function receives a Pub/Sub message when a budget alert fires and can take automated action.
1import { onMessagePublished } from "firebase-functions/v2/pubsub";2import { logger } from "firebase-functions";34// This function is triggered by Cloud Billing budget alerts5// Set up: Billing > Budgets > Connect Pub/Sub topic6export const budgetAlert = onMessagePublished(7 "firebase-budget-alerts",8 async (event) => {9 const data = event.data.message.json;10 const budgetAmount = data.budgetAmount;11 const currentSpend = data.costAmount;12 const percentUsed = (currentSpend / budgetAmount) * 100;1314 logger.warn(15 `Budget alert: ${percentUsed.toFixed(1)}% used ($${currentSpend}/$${budgetAmount})`16 );1718 if (percentUsed > 120) {19 // Critical: Take emergency action20 // Option 1: Disable billing (requires Cloud Billing API)21 // Option 2: Set all function maxInstances to 022 // Option 3: Alert on-call engineer via PagerDuty/Slack23 logger.error("CRITICAL: Budget exceeded 120%. Taking action.");24 }25 }26);Expected result: A Cloud Function automatically responds to budget alerts and can take protective action when spending exceeds thresholds.
Complete working example
1import { onDocumentCreated } from "firebase-functions/v2/firestore";2import { onMessagePublished } from "firebase-functions/v2/pubsub";3import { logger } from "firebase-functions";4import * as admin from "firebase-admin";56admin.initializeApp();78// Safe Firestore trigger with guard field to prevent infinite loops9export const processOrder = onDocumentCreated(10 {11 document: "orders/{orderId}",12 maxInstances: 5, // Cap scaling13 },14 async (event) => {15 if (!event.data) return;16 const data = event.data.data();1718 // Guard: prevent infinite loop19 if (data.processedByFunction === true) return;2021 await event.data.ref.update({22 processedByFunction: true,23 totalWithTax: data.subtotal * 1.1,24 processedAt: admin.firestore.FieldValue.serverTimestamp(),25 });2627 logger.info(`Order ${event.params.orderId} processed`);28 }29);3031// Budget alert handler — triggered by Pub/Sub from Cloud Billing32export const budgetAlert = onMessagePublished(33 {34 topic: "firebase-budget-alerts",35 maxInstances: 1,36 },37 async (event) => {38 const data = event.data.message.json;39 const percentUsed =40 (data.costAmount / data.budgetAmount) * 100;4142 logger.warn(43 `Budget: ${percentUsed.toFixed(1)}% ($${data.costAmount}/$${data.budgetAmount})`44 );4546 // Log to Firestore for dashboard visibility47 await admin.firestore().collection("billingAlerts").add({48 percentUsed,49 costAmount: data.costAmount,50 budgetAmount: data.budgetAmount,51 alertTime: admin.firestore.FieldValue.serverTimestamp(),52 });5354 if (percentUsed > 150) {55 logger.error("CRITICAL: Budget exceeded 150%");56 // Implement your emergency action here57 }58 }59);Common mistakes when avoiding Overbilling in Firebase on the Blaze Plan
Why it's a problem: Assuming Firebase budget alerts will automatically stop charges when the budget is exceeded
How to avoid: Budget alerts are notification-only. They send emails and Pub/Sub messages but do NOT cap spending. You must implement programmatic safeguards or manually monitor usage to prevent overages.
Why it's a problem: Not setting maxInstances on Cloud Functions, allowing unlimited scaling during traffic spikes or bugs
How to avoid: Always set maxInstances on every function. A function without limits can scale to hundreds of instances during a bug or DDoS, generating massive charges.
Why it's a problem: Writing Firestore triggers that modify the same collection they listen to, creating infinite loops
How to avoid: Add a guard field (like processedByFunction: true) and check it at the top of every trigger. Return early if already processed.
Why it's a problem: Reading entire Firestore collections with getDocs(collection(db, 'items')) instead of paginating
How to avoid: Always use limit() to paginate queries. Use getCountFromServer() for counts instead of reading all documents just to count them.
Best practices
- Set up Google Cloud budget alerts at 50%, 80%, 100%, and 150% thresholds before going to production
- Add guard fields to every Firestore trigger to prevent infinite loops — test in the emulator first
- Set maxInstances on every Cloud Function to cap scaling and prevent runaway charges
- Use pagination (limit + startAfter) for all Firestore queries instead of reading entire collections
- Use getCountFromServer() for counts instead of reading all documents and counting client-side
- Monitor Firebase Usage & billing weekly (daily during launches) to catch anomalies early
- Consider programmatic billing controls via Pub/Sub budget alerts for production projects
- Keep Firestore document sizes small and denormalize data to reduce the number of reads per page view
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
Help me set up billing safeguards for my Firebase Blaze plan project. I need: Google Cloud budget alerts at multiple thresholds, a Cloud Function that responds to budget alert Pub/Sub messages, guard fields on all Firestore triggers to prevent infinite loops, and maxInstances limits on all functions.
Create Firebase billing safeguards: set up a Pub/Sub-triggered Cloud Function that logs budget alerts to Firestore and takes action when spending exceeds 150%. Also show a Firestore trigger with a guard field to prevent infinite loops and maxInstances set to 5.
Frequently asked questions
Can I set a hard spending cap on the Firebase Blaze plan?
No. Firebase's FAQ explicitly states: 'No, you cannot cap your usage on the Blaze pricing plan.' Budget alerts are notification-only. For hard limits, you must implement programmatic controls that disable services when budgets are exceeded.
What is the most common cause of unexpected Firebase bills?
Infinite Cloud Function loops — a function that writes to the same Firestore collection it triggers on. This can generate hundreds of thousands of function invocations and Firestore writes within minutes, causing bills of $10,000 or more.
Does the Blaze plan free tier really give me free usage?
Yes. The Blaze plan includes the same free quotas as Spark: 50,000 Firestore reads/day, 20,000 writes/day, 2 million Cloud Functions invocations/month, and more. You only pay for usage above these limits.
How quickly do budget alerts notify me?
Budget alerts can take several hours to process. Google Cloud updates cost data periodically, not in real-time. A fast-moving incident (like an infinite loop) can accumulate significant charges before the first alert arrives.
Should I downgrade to Spark to avoid billing risk?
Spark eliminates billing risk since exceeding quotas simply shuts off the service. However, you lose Cloud Functions, phone authentication, and multiple database instances. If you need these features, stay on Blaze with proper safeguards.
How do I check current Firebase usage?
Go to Firebase Console > your project > Usage & billing. This shows daily reads, writes, function invocations, and storage. For detailed cost breakdowns, use Google Cloud Console > Billing > Reports.
Can Firebase App Check help reduce costs from abuse?
Yes. App Check verifies that requests come from your legitimate app, blocking automated bots and scrapers. This prevents unauthorized usage that could drive up Firestore reads and function invocations.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation