Optimize your Firebase Remote Config usage with 3 best practices for performance and fetch efficiency

Firebase Remote Config gives you flexible, real-time control over your app’s behavior and appearance. This enables capabilities like feature rollouts and cross-platform A/B testing for your apps, all without requiring the toil of deploying new versions or navigating multiple app store updates.

On September 1, 2026, Remote Config will adopt a usage-based billing model. We want to help you ensure your apps run lean, fast, and within cost-effective limits. In this article, we’ll share 3 best practices centered on smart fetch patterns that you can implement today to optimize your Remote Config setup.

Below, we break down how the upcoming usage baseline works and explore three actionable strategies to optimize your Remote Config setup.

A note on the pricing update

Most Firebase Remote Config projects will see no impact; the no-cost tier includes 100,000 daily fetch requests and provides access to all features. Projects exceeding this limit will transition to pay-as-you-go pricing, with existing customers receiving a 3 to 5-month grace period. You can find more details about pricing here

How to optimize your Remote Config usage

Whether you are prototyping, running a growing startup or an enterprise application at scale, managing your network fetch volume is key to delivering a fast, responsive user experience. Efficient configuration management reduces cold-start latency, saves client data and battery usage, and prevents unnecessary network overhead. Plus, in case your user base expands rapidly and drives up usage in the future, streamlining your Remote Config integration can help you ensure your costs remain low..

You can reduce client-side network request traffic significantly by refining how and when apps fetch parameters and when they activate them.

Let’s explore different strategies to make that happen.

Strategy 1: Shift to the “Fetch for Next Session” pattern

A common anti-pattern is using the fetchAndActivate() call - which, as the name implies, both fetches the new values over the network and activates them - on every app launch combined with a short cache expiration period for previously fetched values (e.g. 15 minutes to an hour). The mental model developers have when using this anti-pattern is that every time a user opens their app, they’ll be guaranteed to have the latest values fetched and applied. While there are times this immediate update is necessary (for example, running a daily sales campaign or game promotion), it is important to carefully balance that goal with the impact on your app’s performance and fetch usage.

This approach forces fresh network calls every time the cache expires - generating high fetch volume for users who open the app multiple times a day.

Instead, consider using fetch() and activate() calls separately with a higher minimum fetch interval to adopt a “fetch for next session” model. Note you could still use a fetchAndActivate() call with a higher minimum fetch interval since the fetch() call will only execute a network request if the cache is invalidated, but using the two calls separately helps to solidify the pattern and establish it as a standard practice in your or your team’s application development process. Additionally, by activating separately, you do not run the risk of applying configuration values mid-session and disrupting the user experience.

How this approach works:

  1. Activate immediately on launch: Apply configurations cached from the previous session instantly (0ms network delay).

  2. Fetch in the background with a longer cache (>12 or 24 hours): Request updated configurations asynchronously to refresh the local cache for the next session.

How this optimizes fetch volume: Simply put, a longer minimum fetch interval means less fetch requests. Also, using a pattern to fetch new values for the next session and activating current values for the current session means that your app always loads instantly from the local cache (over a longer validation period) which can also lead to better user experiences. For example, if you set minimumFetchInterval as 24 hours; when a user opens your app 5 or 10 times in a single day, the SDK automatically satisfies launches #2 through #10 directly from the local cache - reducing that user’s daily network request count and your fetch count from 10+ fetches down to just 1. Note, for this example we’re using 24 hours but, in practice, you’ll want to ensure that minimumFetchInterval values work for your use case and they are not arbitrarily high or low.

Here are a few examples of what this implementation would look like for Android, iOS and web apps:

Android (Kotlin)

MainActivity.kt
val remoteConfig = Firebase.remoteConfig

// Set a 24-hour minimum fetch interval (86,400 seconds)
val configSettings = remoteConfigSettings {
  minimumFetchIntervalInSeconds = 86400
}
remoteConfig.setConfigSettingsAsync(configSettings)

// 1. Instantly activate values cached from the LAST session
remoteConfig.activate().addOnCompleteListener {
  applyAppConfigurations()
}

// 2. Fetch new values in the background for the NEXT session
remoteConfig.fetch().addOnCompleteListener { task ->
  if (task.isSuccessful) {
      // Optional: Activate values if needed
  }
}
Copied!

Apple platforms (Swift)

ViewController.swift
let remoteConfig = RemoteConfig.remoteConfig()

// Set a 24-hour minimum fetch interval (86,400 seconds)
let settings = RemoteConfigSettings()
settings.minimumFetchInterval = 86400
remoteConfig.configSettings = settings

// 1. Instantly activate values cached from the LAST session
remoteConfig.activate { changed, error in
  guard error == nil else { return }
  DispatchQueue.main.async {
      self.applyAppConfigurations()
  }
}

// 2. Fetch new values in the background for the NEXT session
remoteConfig.fetch { status, error in
  if status == .success {
      // Optional: Activate values if needed
  }
}
Copied!

Web / JavaScript

App.tsx
import { getRemoteConfig, fetchConfig, activate } from "firebase/remote-config";

const remoteConfig = getRemoteConfig(app);

// Set a 24-hour minimum fetch interval (86,400,000 ms)
remoteConfig.settings.minimumFetchIntervalMillis = 86400000;

// 1. Instantly activate values cached from the LAST session
activate(remoteConfig).then(() => {
applyAppConfigurations();
});

// 2. Fetch new values in the background for the NEXT session
fetchConfig(remoteConfig).then(() => {
// Optional: Activate values if needed
});
Copied!

Strategy 2: Implement conditional “smart” fetching

If the “Fetch for Next Session” pattern introduces too much latency between when you need to update Remote Config values and when they become available in your client apps, consider adopting conditional “smart” fetching.

To implement this effectively, avoid attaching fetch() triggers to broad UI lifecycle hooks, such as every time a screen loads, a tab switches, or a view gains focus.

Instead, trigger fetch requests selectively based on explicit app actions or states, such as:

  • User sign-in events
  • Transitioning into specific user flows where your parameters are used (e.g., entering a checkout funnel, leveling up in a game, etc).

Conversely, avoid triggering fetch requests for routine actions like:

  • When a user opens the app or starts a new session
  • When the app transitions between background and foreground states

Strategy 3: Pair longer fetch windows with realtime Remote Config strategically

Realtime Remote Config allows you to attach listeners and receive configuration updates in real-time. This is ideal for features or user flows that require frequent updating - such as instantly toggling a feature flag when testing a brand new feature, or promoting limited time flash sales.

Using Realtime Remote Config strategically

To maximize the value of Realtime Remote Config, focus on key areas in your application that require instant updates - such as feature flag toggles - and carefully manage listener lifecycle events around those specific components.

This targeted strategy helps ensure that fetch requests for configuration updates occur only when users navigate relevant sections of your app.

Pair this real-time implementation with standard Remote Config fetching set to a longer minimum fetch interval (e.g., 24 to 48 hours). This ensures that inactive users still receive the latest configurations over time, while reducing overall fetch volume and allowing app instances to load fresh values even before navigating to real-time features.

Things to keep in mind when using Realtime Remote Config:

  • Fetch limits: Whenever a parameter is updated in the console, an invalidation signal is sent to listening client apps, triggering fetches that count toward your fetch limits.
  • Battery consumption: Maintaining an open HTTP connection to listen for updates increases battery usage on user devices.

Use Realtime Remote Config correctly to keep your fetches and battery consumption optimal. You can use addOnConfigUpdateListener to add a listener. If you accidentally added multiple listeners in different sections of your app, Remote Config will still only maintain and reuse a single HTTP connection for all listeners. To clean up added listeners, call remove() on each ConfigUpdateListenerRegistration object. To close the open network connection, make sure all added listeners have been removed.

Next steps

By adopting these optimization techniques, you can ensure your app operates efficiently while eliminating unnecessary fetch requests

Since we’re also in the age of agentic development, one way to audit your codebase and your Remote Config usage to ensure you’re following the best practices where applicable in your application by getting help from your favorite coding agent.

Here, I asked Gemini for help to create a prompt I could use with my favorite coding agent (in this case, Antigravity), but you can adapt it with your favorite AI chat interface and coding agent to meet your own setup needs.

The prompt to Gemini:

Create a prompt that I can pass to  <your-favorite-coding-agent> that incorporates and checks for the three core optimization strategies and best practices identified in this blog post: https://firebase.blog/posts/2026/08/optimize-remote-config-usage.
Copied!

This should yield a prompt similar to the following which you can also adjust based on your own project codebase or coding agent configuration and the pass on to your agent:

# Role & Objective
You are an expert mobile and web software engineer and architectural code reviewer. Your objective is to audit this codebase for its implementation of Firebase Remote Config, specifically evaluating it against the three fetch efficiency and performance optimization strategies outlined below, and provide an actionable remediation report.

---

## Remote Config Optimization Checklist

Evaluate the codebase against these 3 core strategies:

### 1. Shift to the "Fetch for Next Session" Pattern
- **Best Practice:** On launch, immediately call `activate()` to apply locally cached parameters with 0ms network latency, while asynchronously triggering `fetch()` in the background with a long minimum fetch interval (e.g., >= 12 to 24 hours / 86,400s).
- **Anti-Pattern:** Calling `fetchAndActivate()` on every app startup paired with short cache expiration windows (e.g., 0–60 minutes), causing redundant HTTP fetch requests every time active users open the app.

### 2. Implement Conditional "Smart" Fetching
- **Best Practice:** Trigger fetch requests selectively based on discrete user milestones or state transitions where parameters are actually consumed (e.g., user sign-in, entering a checkout funnel, or crossing specific functional checkpoints).
- **Anti-Pattern:** Binding `fetch()` or `fetchAndActivate()` calls to broad, frequent UI lifecycle hooks (e.g., every screen mount/load, view focus/appearance, tab switch, or app foreground/background transitions).

### 3. Strategic Realtime Remote Config Management
- **Best Practice:** When using `addOnConfigUpdateListener`, attach listeners dynamically only to components or user flows that require instant updates (e.g., active feature flag rollouts or flash promotions), and explicitly call `remove()` on the listener registration object when the view or component unmounts/destroys to close open HTTP connections.
- **Anti-Pattern:** Global, permanently open Realtime listeners attached across the entire app lifecycle, leading to excessive invalidation-driven fetches and unnecessary battery drain.

---

## Instructions for Execution

1. **Codebase Scan:**
 - Search the repository for all Firebase Remote Config imports, instances, settings (`minimumFetchInterval`, `minimumFetchIntervalInSeconds`, `minimumFetchIntervalMillis`), fetch/activate methods (`fetch()`, `activate()`, `fetchAndActivate()`), and real-time listeners (`addOnConfigUpdateListener`).
 - Check all background jobs, worker threads, and multi-module configurations for independent or recurring Remote Config calls.

2. **Compliance Analysis:**
 - Map every finding to one of the 3 optimization strategies.
 - Flag non-compliant code patterns, evaluate the risk of runaway fetch requests, and note exact file paths and line numbers.

---

## Output Format

Provide a markdown report structured as follows:

### 1. Executive Summary
- Overall assessment of Remote Config fetch efficiency.
- Tally of findings categorized by severity: `[High Risk / Anti-Pattern]`, `[Medium Risk / Needs Optimization]`, `[Compliant]`.

### 2. Detailed Findings by Strategy
For each strategy (1 to 3):
- **Strategy Name:** (e.g., *Strategy 1: Fetch for Next Session*)
- **Status:** `[Compliant]`, `[Needs Optimization]`, or `[High Risk Anti-Pattern]`
- **Location:** `filepath:line_number`
- **Current Code:** Snippet of the existing implementation.
- **Issue Analysis:** Why this approach increases fetch volume, battery drain, or latency.
- **Recommended Refactoring:** Code snippet showing the corrected implementation.

### 3. Immediate Action Plan
- A step-by-step prioritized checklist to resolve all identified anti-patterns and ghost fetches.
Copied!

If these strategies helped with your current implementation or inspired you to get started with Remote Config, we would love to hear about your experience on X or LinkedIn!