Firexport logo

FirexportBlog

Firebase Remote Config pricing: what your app will pay

Since September 1, 2026, Firebase Remote Config is priced by how often apps fetch their config. The first 100,000 fetches a day are free on every plan. Above that, Blaze projects pay per fetch and Spark projects are eventually throttled. Most apps stay under the line. Whether yours does depends less on how many users you have than on one setting in your code: the minimum fetch interval.

In short

  • Under 100,000 fetches a day per project: nothing changes, on Spark or Blaze. How to check
  • An existing Spark project over the line: upgrading to Blaze before November 15, 2026 moves the start of billing from December 1, 2026 to February 1, 2027. The dates
  • Above the line on Blaze: $0.06 per 10,000 fetches, and $0.01 per 10,000 past 10 million a day. 1 million fetches a day is about $162 a month. Your estimate
  • The default 12-hour interval holds a device to about two fetches a day. A shorter interval, fetch(0), real-time updates and server-side loads are what push apps over. The fixes

The prices

Spark (no-cost)Blaze (pay as you go)
Up to 100,000 fetches a dayFreeFree
100,001 to 10,000,000 a dayThrottled, after a 30-day grace period$0.06 per 10,000 ($0.000006 each)
Over 10,000,000 a dayThrottled$0.01 per 10,000 ($0.000001 each)
A/B Testing, rollouts, personalizationIncludedIncluded
  • The 100,000 is per project. An Android app, an iOS app and a website in the same project share it.
  • It is per day, and a quiet day doesn’t make up for a busy one. A launch day with a million fetches costs $5.40 even if the rest of the month stays under 100,000.
  • Neither your code nor your SDK version has to change. Firebase meters fetches on its side, on both plans.

When the new pricing reaches your project

Projects that turned on Remote Config before September 1, 2026 get a transition period first. Which one depends on the plan the project is on:

Your projectThe new rules apply fromOver 100,000 fetches a day
Started using Remote Config on or after September 1, 2026AlreadySpark: throttled after 30 days. Blaze: billed.
Existing, on BlazeFebruary 1, 2027Billed. Nothing to do.
Existing, on Spark, upgraded to Blaze before November 15, 2026February 1, 2027Billed
Existing, staying on SparkDecember 1, 2026Throttled after 30 days

The pricing page doesn’t say what happens to a Spark project upgraded between November 15 and December 1. If that is your plan, count on billing from December 1.

Should you upgrade before November 15?

  • If your project makes fewer than 100,000 fetches a day, no. Spark keeps working as before, and so does Blaze.
  • If it makes more, or is close, upgrading before November 15 buys two months, December and January, to bring fetches down before anything is billed. The alternative on Spark is throttling, which is worse than a few dollars for most apps.
  • Blaze links the project to a Cloud Billing account and has no spending cap. Other products keep their no-cost usage, and you pay only for what goes past it. Set a budget alert when you upgrade (below).

What throttling means on Spark

The first day a Spark project goes over 100,000 fetches starts a 30-day grace period, during which every fetch is still served. The countdown doesn’t pause or reset if usage drops back under the line in the meantime. From day 31, fetches past the 100,000th of each day are refused. The app keeps running, but a device whose fetch is refused stays on the values it already has, or on its in-app defaults: a rollout, an A/B test or a kill switch doesn’t reach it. Project admins get emails and a console banner as usage approaches the limit, so a warning in your inbox is the time to look.

Count your fetches

A fetch is a request that reaches the Remote Config server:

CountsDoesn’t count
fetch() and fetchAndActivate() when they go to the serverThe same calls inside the minimum fetch interval, which the SDK answers from the device
The download after a real-time updateKeeping the real-time connection open
Reading the template with the REST API or an Admin SDK, server-side Remote Config includedactivate(), getString() and every other read of values on the device

Calls that other Firebase products make internally don’t count either. To see how many fetches your project makes:

  • Firebase console: Usage and billing, Remote Config section. On Spark, the quota progress card shows the day’s fetches against 100,000. On Blaze, a bar chart splits each day across the price tiers.
  • Google Cloud console: IAM & Admin > Quotas & System Limits, filtered to firebaseremoteconfig.googleapis.com, on either plan. On Blaze, Cloud Billing reports show the charges under the SKU Fetch Requests: 37B1-4623-6F54 for projects created on or after September 1, 2026, 598C-0184-404A for older ones.

Then divide a typical day’s fetches by that day’s active users in Analytics. With the default 12-hour interval and no real-time listener, a device can’t fetch more than about twice a day, so the result is 2 or less, a bit more if many users have the app on several devices or reach your website from several browsers. Well above 2, something in your code skips the interval, and the section on extra fetches shows where to look.

What your app will pay

Daily fetches are daily active users times fetches per user per day. Put in your own numbers, or the ones you expect after a launch:

Estimate your Remote Config bill

With the default 12-hour fetch interval and no real-time listener, a device makes at most about 2 a day.

Fetches a day
200,000
On Blaze
$0.60 a day
$18.00 for 30 days like it
On Spark
100,000 over the limit. After the 30-day grace period, those fetches (50% of the day’s) are throttled.

Some sizes, on Blaze, for a 30-day month of identical days:

Daily active usersFetches per userFetches a dayA month on Blaze
10,000220,000$0.00
100,0002200,000$18.00
100,000101,000,000$162.00
1,000,00022,000,000$342.00
1,000,0001010,000,000$1,782.00
1,000,0003030,000,000$2,382.00

At a million daily users, going from 10 fetches a user to 2 saves about $1,440 a month. Turned around, here is how many daily users fit in the free 100,000:

Fetches per user per dayFree up to about
1100,000 daily active users
250,000 daily active users
520,000 daily active users
205,000 daily active users

Where extra fetches come from, and how to cut them

Every fetch method checks the minimum fetch interval first. Inside it, the SDK returns the values it already has and no request is made. So the fetches an app makes come down to how that interval is set, and to the few things that go around it. Start by finding every place your code sets or skips it:

grep -rniE "minimumfetchinterval|fetch\(0|expirationduration|timespan\.zero" \
  --exclude-dir={node_modules,build,Pods,.dart_tool,.gradle} .

1. A short fetch interval left in production

The default is 12 hours on Android, Apple platforms, the web and Flutter. Shorter values come from development setups and from samples: Firebase’s own Flutter getting-started code sets one hour “to allow for frequent refreshes”, and many tutorials copy it. Shipped as is, an hour lets each device fetch once per session that starts an hour after the last fetch, up to 24 times a day. Keep short values to debug builds:

// Android (Kotlin). On AGP 8+, BuildConfig.DEBUG needs
// buildFeatures { buildConfig = true } in build.gradle.
Firebase.remoteConfig.setConfigSettingsAsync(
    remoteConfigSettings {
        // 12 hours in release builds
        minimumFetchIntervalInSeconds = if (BuildConfig.DEBUG) 60 else 43200
    }
)
// iOS (Swift)
let settings = RemoteConfigSettings()
#if DEBUG
settings.minimumFetchInterval = 60
#else
settings.minimumFetchInterval = 43200 // 12 hours
#endif
RemoteConfig.remoteConfig().configSettings = settings
// Flutter. kDebugMode is in package:flutter/foundation.dart.
await FirebaseRemoteConfig.instance.setConfigSettings(RemoteConfigSettings(
  fetchTimeout: const Duration(minutes: 1),
  minimumFetchInterval:
      kDebugMode ? const Duration(minutes: 1) : const Duration(hours: 12),
));
// Web. 12 hours is the default, so deleting the line does the same.
const remoteConfig = getRemoteConfig(app);
remoteConfig.settings.minimumFetchIntervalMillis = 12 * 60 * 60 * 1000;

For values that rarely change, Firebase suggests going further, to 24 or 48 hours. If you shortened the interval so that changes reach users quickly, real-time updates (4) do that with one fetch per change instead of one per session.

2. A fetch(0) from a “Remote Config not updating” fix

A common answer to “my new values don’t show up” is to pass an interval of zero to the fetch call. On Android and Apple platforms that argument wins over the settings, so the call goes to the server every time, however the interval is configured:

// Each of these ignores the interval and goes to the server on every call:
remoteConfig.fetch(0)                                // Android
remoteConfig.fetch(withExpirationDuration: 0)        // iOS
remoteConfig.FetchAsync(TimeSpan.Zero)               // Unity

Remove the argument and let the configured interval apply. The values a user sees still update within 12 hours, or at once with a real-time listener.

3. Fetching on every screen, resume or background wake-up

A fetch in every screen’s setup, every onResume, every component mount, or in Application.onCreate, which also runs when a push message or a background job wakes the app, multiplies whatever the interval allows. With 12 hours it adds little, since most of those calls are answered on the device. With a short interval or fetch(0) it is where large counts come from. Fetch once, when the app starts in the foreground, and read values with the getters everywhere else. Firebase calls the background ones “ghost fetches” and lists them among the first things to audit.

4. Real-time updates and frequent publishes

A real-time listener keeps a connection open while the app is in the foreground, and the connection is free. When you publish a new template version, every listening device downloads it, and each download is a fetch that ignores the interval. A device that opens the app later with an older version gets it the same way. So each publish, whatever it changes, costs up to one fetch per device that runs your app before the next one.

200,000 devices on a day with 10 publishes is up to 2 million fetches from real-time alone, about $12 that day at $0.06 per 10,000. Batch edits into one publish instead of several small ones, and add the listener only where an instant change matters, such as a kill switch.

5. Loading the template on every server request

Server-side Remote Config, still in Preview, downloads the whole template with an Admin SDK, and each download is a fetch. Calling getServerTemplate() inside a Cloud Function or Cloud Run handler makes one per request, so a busy endpoint alone can go past 100,000 a day. Load it once per server instance and refresh it on a timer:

import { initializeApp } from "firebase-admin/app";
import { getRemoteConfig } from "firebase-admin/remote-config";

initializeApp();

const DEFAULTS = { welcome_message: "Hello" };
// At most one fetch per server instance every 10 minutes.
const REFRESH_MS = 10 * 60 * 1000;

let templatePromise; // one template per server instance, kept between requests
let loadedAt = 0;

export async function getConfig() {
  if (!templatePromise) {
    loadedAt = Date.now();
    templatePromise = getRemoteConfig()
      .getServerTemplate({ defaultConfig: DEFAULTS })
      .catch((err) => {
        templatePromise = undefined; // try again on the next request
        throw err;
      });
  }

  const template = await templatePromise;

  if (Date.now() - loadedAt > REFRESH_MS) {
    loadedAt = Date.now();
    // Refreshes in the background. Until it lands, requests get the
    // values already loaded.
    template.load().catch((err) => console.error("Refresh failed", err));
  }

  return template.evaluate();
}

Refreshing every 10 minutes is 144 fetches a day for each running instance, whatever the traffic. Scripts and CI jobs that read the template through the REST API count too, though rarely enough to matter.

Set a budget alert when you move to Blaze

Blaze has no hard cap. In the Google Cloud console, open Billing > Budgets & alerts and create a budget for the project, near what the calculator above gives you. By default it emails billing admins at 50%, 90% and 100% of the amount. It doesn’t stop spending, so treat the first email as the signal to look at the Remote Config chart on the Usage and billing page.

Questions

Is Firebase Remote Config still free?

Up to 100,000 fetches a day per project, on Spark and on Blaze. Reading values on the device, A/B Testing, rollouts and personalization cost nothing extra. Above 100,000 a day, Blaze projects pay $0.06 per 10,000 fetches and Spark projects are throttled after a 30-day grace period.

When do existing projects start paying?

Projects on Blaze, on February 1, 2027. Projects on Spark aren’t billed: the 100,000 limit applies to them from December 1, 2026, unless they upgrade to Blaze before November 15, 2026, in which case billing starts on February 1, 2027.

Is the 100,000 limit per app or per project?

Per project. All the apps registered in a Firebase project share it.

Do I need to change my code or update the SDK?

No. Metering happens on Firebase’s servers, and switching between Spark and Blaze needs no change in the app. Changing code only matters if you want fewer fetches.

Does real-time Remote Config cost more?

The open connection doesn’t count. Each download of a new template version after you publish does, one per device, and it ignores the minimum fetch interval.

Why aren’t my users getting new Remote Config values?

Usually the minimum fetch interval: a device keeps its values for up to 12 hours by default, and fetched values only apply after activate(). Since the new pricing, a Spark project can also be throttled once it has been over 100,000 fetches a day for more than 30 days. Check the Remote Config section of Usage and billing before shortening the interval, which would make the throttling worse.

Sources

All posts →