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.

> [!NOTE]
> **Note:** This example uses 24 hours, but in practice, make sure that your `minimumFetchInterval` values work for your use case and aren't arbitrarily high or low.

The following examples show what this implementation looks like for Android,
Apple platforms, and web apps:

### Android

```kotlin
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+

```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
    }
}
```

### Web

```javascript
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](https://firebase.google.com/docs/remote-config/real-time-best-practices.md.txt).
- Explore [Firebase Remote Config loading strategies](https://firebase.google.com/docs/remote-config/loading.md.txt).