AI & Technology

How to Cut Your Firebase Bill: A Line-by-Line Cost Audit (2026)

Simon Dziak
Simon Dziak
Owner & Head Developer
October 12, 2026•10 min

Most Firebase bills that keep creeping up have a few specific causes, and you can find them in an afternoon. Measure what each service actually does, price it at Google's list prices, then rank every possible saving by dollars a month and by the risk your users would notice. Guessing ("let's turn off min instances everywhere") usually trades a small saving for slower screens.

This is the method App369 uses for its fixed-price Firebase Cost-Cut Audit. It is also how Simon audits the production Firebase project behind his own SaaS, Workspace369, which runs about 980 Cloud Run services. On that project, the audit found that roughly 42% of steady-state spend was recoverable. It was a small bill, and not every finding was applied, but the pattern is common.

Why Firebase bills grow quietly

Firebase's pay-as-you-go Blaze plan bills each product separately, so there is rarely one obvious line item. The usual sources are:

  • 2nd gen Cloud Functions run on Cloud Run. Every function is its own Cloud Run service with its own memory, CPU, concurrency and minimum-instance settings. A project with 100 functions has 100 sets of settings that nobody reviews after launch.
  • Minimum instances bill while idle. Keeping an instance warm removes cold starts, but you pay for it around the clock, whether or not anyone calls the function.
  • Firestore bills per document read. A screen that listens to a whole collection, or a scheduled job that scans one every few minutes, multiplies reads with no visible symptom.
  • Background work has no user to complain. Retry loops, triggers that fire other triggers, and verbose logging run at full speed until the invoice arrives.

Step 1: Measure before you cut

Start from data, not settings.

  1. Billing export. If Cloud Billing export to BigQuery is on, you have actual spend by service and SKU. If it isn't, turn it on now; it only collects data from the day you enable it.
  2. Usage from Cloud Monitoring. For each Cloud Run service, pull 7 and 30 days of request count and billable instance time (run.googleapis.com/container/billable_instance_time). For Firestore, pull document reads, writes and deletes.
  3. List prices. The Cloud Billing Catalog API returns the current price of every SKU in your region, so each estimate is priced from Google's own numbers rather than a blog post.

Multiply usage by price, per service, and you have an estimated monthly bill by service. Sort it. In most projects a handful of services account for most of the money.

Step 2: Always-on minimum instances

List every service with minInstances above zero:

gcloud run services list --format=json \
  | jq -r '.[] | [.metadata.name, (.spec.template.metadata.annotations["autoscaling.knative.dev/minScale"] // "0")] | @tsv' \
  | awk '$2 > 0'

For each one, ask whether a user waits on it. A login or checkout function may deserve a warm instance. A nightly report or a webhook that Stripe retries anyway usually doesn't. In code, the setting lives on the function (minInstances in the Firebase Functions v2 options), so change it there, not only in the console, or the next deploy puts it back.

Step 3: Memory, CPU and concurrency

  • Memory. Functions are often deployed at 1 GiB or more "to be safe". Compare the configured memory with the memory utilization metric and size down where the peak is far below the limit.
  • Concurrency. 2nd gen functions can serve many requests per instance (80 by default with a full CPU); 1st gen functions serve one. A function forced to concurrency: 1 scales out an instance per request.
  • Timeouts. A long timeout on a function that hangs on a slow upstream keeps a billed instance busy until it gives up.

Step 4: Firestore reads

Read costs come from patterns, not single queries:

  • Collection listeners on busy screens. A dashboard that listens to every document in a collection pays for every change, for every open client. Paginate, filter, or listen to a summary document instead.
  • Counting by reading. Use aggregation queries (count(), sum(), average()) instead of downloading documents to count them.
  • Scheduled scans. A job that reads a whole collection every five minutes to find a few changed documents should query on an indexed updatedAt field instead.

Step 5: Trigger fan-out and retry storms

Event-triggered functions can multiply quietly:

  • A function that writes to the document that triggered it can re-trigger itself.
  • One write can fan out to several triggers, each of which writes again.
  • A function with retries enabled that fails on the same bad data keeps retrying, for hours or days, and every attempt is billed.

Look for invocation counts that are far higher than the user actions behind them, and for error rates that never drop.

Step 6: Secrets, logs and images

These are smaller lines, but they add up across many services:

  • Secret Manager bills for active secret versions and for access operations. Disable or destroy versions you no longer use, and read a secret once per instance rather than once per request.
  • Cloud Logging charges for ingestion beyond the free monthly allotment. Logging full request payloads is expensive, and it can also write customer data into your logs.
  • Artifact Registry stores a container image for every function deploy. A cleanup policy keeps only the recent ones.

Step 7: AI and Vertex AI usage

If your app calls Gemini or another model, look at tokens per user action, not just total spend. Common fixes are caching repeated prompts, trimming the context you send, and putting a per-user or per-workspace limit on expensive features. If you resell AI features, check that your price covers your cost per call; that is a revenue leak, not a cloud cost, but it shows up in the same audit.

Rank the savings, then decide

Write every finding in one table and sort it by dollars a month:

Finding$/monthUser-visible riskEffortHow to roll back
Example: min instances on a nightly jobmeasuredNone1 lineSet minInstances back
Example: collection listener on the dashboardmeasuredLowHalf a dayRevert the query
Example: 1 GiB on a 120 MiB functionmeasuredLow1 lineRaise memory again

Apply the low-risk, high-dollar rows first. Leave anything on a latency-sensitive path until you've watched it in staging.

When to get help

If the bill matters but nobody on the team has a free week, App369 runs this audit for a fixed $750, delivered in 5 business days with read-only, temporary access. You get the bill by service, the ranked savings table, a CSV of every service, and the exact commands to apply each change. Nothing in your project is changed. If you are also worried about who can read what, the Firebase Security Rules guide covers the access side.

Frequently Asked Questions

Why is my Firebase bill so high when traffic is low?

Usually because something runs without traffic: minimum instances kept warm around the clock, scheduled functions that scan collections, or triggers that re-fire. Low traffic with a high bill points to background work or idle capacity, not to users.

Do minimum instances cost money when nobody calls the function?

Yes. A minimum instance is kept running so it can answer without a cold start, and it is billed while idle. Keep minimum instances only on functions where a user is waiting for the response.

How do I see the cost of each Cloud Function?

Turn on Cloud Billing export to BigQuery for actual spend by SKU, and use Cloud Monitoring's request count and billable instance time per Cloud Run service. 2nd gen functions appear as Cloud Run services, so each function's usage can be priced separately.

Will cutting costs make my app slower?

Only if you cut on the wrong path. Rank each saving by user-visible risk: background jobs, webhooks and reports can usually scale to zero, while login, checkout and screen-loading functions may need warm instances.

Can I lower my Firebase bill without changing code?

Partly. Minimum instances, memory, concurrency and timeouts can be changed in configuration. Firestore read patterns, trigger loops and logging volume usually need code changes, and settings changed only in the console are overwritten by the next deploy if the code says otherwise.

Tags
#firebase cost #firebase pricing #cloud functions cost #cloud run cost #google cloud cost optimization #firestore reads
Share:

Related Resources

Related Articles