Firebase Remote Config gives you flexible 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 deploying new versions or navigating multiple app store updates.
Whether you're prototyping, running a growing startup, or managing 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. In addition, if your user base expands rapidly and drives up usage in the future, streamlining your Remote Config integration helps ensure that your usage remains efficient.
You can reduce client-side network request traffic significantly by refining how and when apps fetch parameters and when they activate them.
Shift to the "fetch for next session" pattern
A common pattern to avoid is using the fetchAndActivate call—which both
fetches new values over the network and activates them—on every app launch
combined with a short cache expiration period for previously fetched values (for
example, 15 minutes to an hour). The mental model behind this approach is that
every time a user opens the app, they always have the latest values
fetched and applied. While there are times when an immediate update is necessary
(for example, running a daily sales campaign or game promotion), it's important
to 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. You can still
use fetchAndActivate with a higher minimum fetch interval since fetch only
executes a network request if the cache is invalidated, but using the two calls
separately helps solidify the pattern and establish it as a standard practice in
your application development process. Additionally, by activating separately,
you don't run the risk of applying configuration values mid-session and
disrupting the user experience.
How this approach works
- Activate immediately on launch: Apply configurations cached from the previous session instantly (0 ms network delay).
- Fetch in the background with a longer cache (for example, more than 12 or 24 hours): Request updated configurations asynchronously to refresh the local cache for the next session.
How this optimizes fetch volume
A longer minimum fetch interval results in fewer fetch requests. Fetching new values for the next session and activating cached values for the current session means that your app loads instantly from the local cache over a longer validation period, leading to better user experiences.
For example, if you set minimumFetchInterval to 24 hours and 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 from 10 or more fetches down to 1.
The following examples show what this implementation looks like for Android, Apple platforms, and web apps:
Android
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 } }
iOS+
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 } }
Web
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 });
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 (for example, entering a checkout funnel or leveling up in a game)
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
Next steps
- Learn how to use real-time Remote Config strategically.
- Explore Firebase Remote Config loading strategies.