Data saving mode

Data saving mode is available for Early Access

Data saving mode is supported in the SDKs listed below. It is also supported in the Relay Proxy.

Data saving mode is only available to members of LaunchDarkly’s Early Access Program (EAP). If you want access to this feature, join the EAP.

This topic explains how data saving mode works in the LaunchDarkly SDKs that support it, listed below. The Relay Proxy also supports data saving mode.

Server-side SDKs in data saving mode first open a polling connection to LaunchDarkly. The initial payload from this connection contains the data the SDK will need to operate and perform flag evaluations.

Subsequently, server-side SDKs in data saving mode open a streaming connection and receive realtime flag configuration changes over the stream. These configuration changes include only the difference between the server-side SDK’s stored configuration and the latest configuration in LaunchDarkly. The SDKs use in-memory data for the unchanged aspects of the flag configuration.

The SDKs fall back to using a polling connection if LaunchDarkly streaming is unavailable. Data saving mode includes additional configuration options that let you set a backup data source, enabling automatic failover if a connection is unavailable.

Depending on the number of flags in your project and the complexity of their configuration, data saving mode can significantly improve performance, including reducing your network costs when in polling mode or on reconnection. Additionally, SDKs in data saving mode have reduced memory and CPU usage overall.

Track service connection usage by application

When using data saving mode, you can track which applications are consuming service connections by configuring application metadata. Set the applicationId in your SDK configuration to see a per-application breakdown on the Service connections usage page under the SDK App ID dimension. Server-side streaming connections without applicationId configured appear as “Unknown.” To learn how, read Application metadata configuration.

Server-side SDKs

This feature is available in the following SDKs:

.NET (server-side)

To enable data saving mode:

  1. If you are using the Relay Proxy, upgrade your Relay Proxy to version 9.0.0-rc.1 or later.
  2. Upgrade your .NET (server-side) SDK to version 8.11 or later.
  3. Update your SDK configuration to enable the DataSystem configuration option.

Here’s how to enable the DataSystem configuration option:

Standard setup

.NET (server-side) SDK v8.11+
1using LaunchDarkly.Sdk.Server;
2
3var config = Configuration.Builder("YOUR_SDK_KEY")
4 .DataSystem(Components.DataSystem().Default())
5 .Build();
6
7var client = new LdClient(config);

We recommend the standard data system configuration for most customers. It uses a combination of streaming and polling to initialize the SDK, provide real time updates, and switch between streaming and polling automatically to provide redundancy.

Relay proxy with LaunchDarkly API fallback

.NET (server-side) SDK v8.11+
1using LaunchDarkly.Sdk.Server;
2using LaunchDarkly.Sdk.Server.Integrations;
3
4var relayUri = new Uri("http://my-relay-proxy:8030");
5var relayEndpoints = Components.ServiceEndpoints().RelayProxy(relayUri);
6
7var config = Configuration.Builder("YOUR_SDK_KEY")
8 .DataSystem(
9 Components.DataSystem().Custom()
10 .Initializers(
11 DataSystemComponents.Polling()
12 .ServiceEndpointsOverride(relayEndpoints),
13 DataSystemComponents.Polling()
14 )
15 .Synchronizers(
16 DataSystemComponents.Streaming()
17 .ServiceEndpointsOverride(relayEndpoints),
18 DataSystemComponents.Streaming(),
19 DataSystemComponents.Polling()
20 )
21 )
22 .Build();
23
24var client = new LdClient(config);

File-based bootstrap with live updates

.NET (server-side) SDK v8.11+
1using LaunchDarkly.Sdk.Server;
2using LaunchDarkly.Sdk.Server.Integrations;
3
4var config = Configuration.Builder("YOUR_SDK_KEY")
5 .DataSystem(
6 Components.DataSystem().Custom()
7 .Initializers(
8 FileData.DataSource().FilePaths("flags.json"),
9 DataSystemComponents.Polling()
10 )
11 .Synchronizers(
12 DataSystemComponents.Streaming(),
13 DataSystemComponents.Polling()
14 )
15 )
16 .Build();
17
18var client = new LdClient(config);

To learn more, read DataSystemModes for information about pre-configured data system modes, and DataSystemBuilder for information on additional configuration options.

Go

To enable data saving mode:

  1. If you are using the Relay Proxy, upgrade your Relay Proxy to version 9.0.0-rc.1 or later.
  2. Upgrade your Go SDK to version 7.11 or later.
  3. Update your SDK configuration to enable the DataSystem configuration option.

Here’s how to enable the DataSystem configuration option:

Standard setup

Go SDK v7.11+
1import (
2 "github.com/launchdarkly/go-sdk-common/v3/ldcontext"
3 ld "github.com/launchdarkly/go-server-sdk/v7"
4 "github.com/launchdarkly/go-server-sdk/v7/ldcomponents"
5)
6
7var config ld.Config
8
9config.DataSystem = ldcomponents.DataSystem().Default()
10
11client, _ := ld.MakeCustomClient("YOUR_SDK_KEY", config, 5*time.Second)

We recommend the standard data system configuration for most customers. It uses a combination of streaming and polling to initialize the SDK, provide real time updates, and switch between streaming and polling automatically to provide redundancy.

Relay proxy with LaunchDarkly API fallback

Go SDK v7.11+
1import (
2 ld "github.com/launchdarkly/go-server-sdk/v7"
3 "github.com/launchdarkly/go-server-sdk/v7/ldcomponents"
4)
5
6var config ld.Config
7
8relayURI := "http://my-relay-proxy:8030"
9
10config.DataSystem = ldcomponents.DataSystem().Custom().
11 Initializers(
12 ldcomponents.PollingDataSourceV2().BaseURI(relayURI).AsInitializer(),
13 ldcomponents.PollingDataSourceV2().AsInitializer(),
14 ).
15 Synchronizers(
16 ldcomponents.StreamingDataSourceV2().BaseURI(relayURI),
17 ldcomponents.StreamingDataSourceV2(),
18 ldcomponents.PollingDataSourceV2(),
19 )
20
21client, _ := ld.MakeCustomClient("YOUR_SDK_KEY", config, 5*time.Second)

File-based bootstrap with live updates

Go SDK v7.11+
1import (
2 ld "github.com/launchdarkly/go-server-sdk/v7"
3 "github.com/launchdarkly/go-server-sdk/v7/ldcomponents"
4 "github.com/launchdarkly/go-server-sdk/v7/ldfiledatav2"
5)
6
7var config ld.Config
8
9config.DataSystem = ldcomponents.DataSystem().Custom().
10 Initializers(
11 ldfiledatav2.DataSource().FilePaths("flags.json").AsInitializer(),
12 ldcomponents.PollingDataSourceV2().AsInitializer(),
13 ).
14 Synchronizers(
15 ldcomponents.StreamingDataSourceV2(),
16 ldcomponents.PollingDataSourceV2(),
17 )
18
19client, _ := ld.MakeCustomClient("YOUR_SDK_KEY", config, 5*time.Second)

To learn more, read DataSystem. For information on additional configuration options, read DataSystemConfiguration.

Java

To enable data saving mode:

  1. If you are using the Relay Proxy, upgrade your Relay Proxy to version 9.0.0-rc.1 or later.
  2. Upgrade your Java (server-side) SDK to version 7.11 or later.
  3. Update your SDK configuration to enable the dataSystem configuration option.

Here’s how to enable the dataSystem configuration option:

Standard setup

Java SDK v7.11+
1import com.launchdarkly.sdk.server.*;
2
3LDConfig config = new LDConfig.Builder()
4 .dataSystem(Components.dataSystem().defaultMode())
5 .build();
6
7LDClient client = new LDClient("YOUR_SDK_KEY", config);

We recommend the default data system configuration for most customers. It uses a combination of streaming and polling to initialize the SDK, provide real time updates, and switch between streaming and polling automatically to provide redundancy.

Relay proxy with LaunchDarkly API fallback

Java SDK v7.11+
1import com.launchdarkly.sdk.server.*;
2import com.launchdarkly.sdk.server.integrations.*;
3
4import java.net.URI;
5
6URI relayUri = URI.create("http://my-relay-proxy:8030");
7ServiceEndpointsBuilder relayEndpoints = Components.serviceEndpoints().relayProxy(relayUri);
8
9LDConfig config = new LDConfig.Builder()
10 .dataSystem(
11 Components.dataSystem().custom()
12 .initializers(
13 DataSystemComponents.pollingInitializer()
14 .serviceEndpointsOverride(relayEndpoints),
15 DataSystemComponents.pollingInitializer()
16 )
17 .synchronizers(
18 DataSystemComponents.streamingSynchronizer()
19 .serviceEndpointsOverride(relayEndpoints),
20 DataSystemComponents.streamingSynchronizer(),
21 DataSystemComponents.pollingSynchronizer()
22 )
23 )
24 .build();
25
26LDClient client = new LDClient("YOUR_SDK_KEY", config);

File-based bootstrap with live updates

Java SDK v7.11+
1import com.launchdarkly.sdk.server.*;
2import com.launchdarkly.sdk.server.integrations.*;
3
4LDConfig config = new LDConfig.Builder()
5 .dataSystem(
6 Components.dataSystem().custom()
7 .initializers(
8 FileData.initializer().filePaths("flags.json"),
9 DataSystemComponents.pollingInitializer()
10 )
11 .synchronizers(
12 DataSystemComponents.streamingSynchronizer(),
13 DataSystemComponents.pollingSynchronizer()
14 )
15 )
16 .build();
17
18LDClient client = new LDClient("YOUR_SDK_KEY", config);

To learn more, read DataSystemModesfor information about pre-configured data system modes, and DataSystemBuilder for information on additional configuration options.

Node.js (server-side)

To enable data saving mode:

  1. If you are using the Relay Proxy, upgrade your Relay Proxy to version 9.0.0-rc.1 or later.
  2. Upgrade your Node.js (server-side) SDK to version 9.10 or later.
  3. Update your SDK configuration:
    • Enable the dataSystem configuration option.
    • Migrate existing LDOptions fields. The following existing options were previously top-level LDOptions fields and are part of the dataSystem configuration as of version 9.10: persistentStore, stream, streamInitialReconnectDelay, pollInterval, useLDD.

Here’s how to enable the dataSystem configuration option:

Standard setup

Node.js (server-side) SDK v9.10+
1const ldClient = LaunchDarkly.init('YOUR_SDK_KEY', {
2 dataSystem: {
3 dataSource: {
4 dataSourceOptionsType: 'standard',
5
6 // if you use the stream, streamInitialReconnectDelay, or pollInterval options,
7 // these options are now part of the dataSystem options,
8 // and are set within the dataSource option
9 }
10 // if you use the persistentStore or useLDD option,
11 // these options are now part of the dataSystem option
12 }
13});

We recommend the standard data source option for most customers. It uses a combination of streaming and polling to initialize the SDK, provide real time updates, and switch between streaming and polling automatically to provide redundancy.

File-based bootstrap with live updates

Node.js (server-side) SDK v9.10+
1const ldClient = LaunchDarkly.init('YOUR_SDK_KEY', {
2 dataSystem: {
3 dataSource: {
4 dataSourceOptionsType: 'custom',
5 initializers: [
6 { type: 'file', paths: ['flags.json'] },
7 { type: 'polling' },
8 ],
9 synchronizers: [
10 { type: 'streaming' },
11 { type: 'polling' },
12 ],
13 }
14 }
15});

To learn more, read dataSystem. For information on additional configuration options, read LDDataSystemOptions.

Python

To enable data saving mode:

  1. If you are using the Relay Proxy, upgrade your Relay Proxy to version 9.0.0-rc.1 or later.
  2. Upgrade your Python SDK to version 9.13 or later.
  3. Update your SDK configuration to enable the DataSystem configuration option.

Here’s how to enable the DataSystem configuration option:

Standard setup

Python SDK v9.13+
1import ldclient
2from ldclient.config import Config
3from ldclient import datasystem
4
5ldclient.set_config(
6 Config(
7 "YOUR_SDK_KEY",
8 datasystem_config=datasystem.default().build(),
9 )
10)
11
12client = ldclient.get()

We recommend the standard data system configuration for most customers. It uses a combination of streaming and polling to initialize the SDK, provide real time updates, and switch between streaming and polling automatically to provide redundancy.

Relay proxy with LaunchDarkly API fallback

Python SDK v9.13+
1import ldclient
2from ldclient.config import Config
3from ldclient import datasystem
4
5relay_uri = "http://my-relay-proxy:8030"
6
7ldclient.set_config(
8 Config(
9 "YOUR_SDK_KEY",
10 datasystem_config=datasystem.custom()
11 .initializers([
12 datasystem.polling_ds_builder().base_uri(relay_uri),
13 datasystem.polling_ds_builder(),
14 ])
15 .synchronizers(
16 datasystem.streaming_ds_builder().base_uri(relay_uri),
17 datasystem.streaming_ds_builder(),
18 datasystem.polling_ds_builder(),
19 )
20 .build(),
21 )
22)
23
24client = ldclient.get()

File-based bootstrap with live updates

Python SDK v9.13+
1import ldclient
2from ldclient.config import Config
3from ldclient import datasystem
4
5ldclient.set_config(
6 Config(
7 "YOUR_SDK_KEY",
8 datasystem_config=datasystem.custom()
9 .initializers([
10 datasystem.file_ds_builder(paths=["flags.json"]),
11 datasystem.polling_ds_builder(),
12 ])
13 .synchronizers(
14 datasystem.streaming_ds_builder(),
15 datasystem.polling_ds_builder(),
16 )
17 .build(),
18 )
19)
20
21client = ldclient.get()

To learn more, read ldclient.datasystem. For information on additional configuration options, read DataSystemConfig.

Ruby

To enable data saving mode:

  1. If you are using the Relay Proxy, upgrade your Relay Proxy to version 9.0.0-rc.1 or later.
  2. Upgrade your Ruby SDK to version 8.12.0 or later.
  3. Update your SDK configuration to enable the data_system_config configuration option.

Here’s how to enable the data_system_config configuration option:

Standard setup

Ruby SDK v8.12.0+
1require 'ldclient-rb'
2
3config = LaunchDarkly::Config.new(
4 data_system_config: LaunchDarkly::DataSystem.default.build
5)
6
7client = LaunchDarkly::LDClient.new("YOUR_SDK_KEY", config)

We recommend the standard data system configuration for most customers. It uses a combination of streaming and polling to initialize the SDK, provide real time updates, and switch between streaming and polling automatically to provide redundancy.

Relay proxy with LaunchDarkly API fallback

Ruby SDK v8.12.0+
1require 'ldclient-rb'
2
3relay_uri = "http://my-relay-proxy:8030"
4
5config = LaunchDarkly::Config.new(
6 data_system_config: LaunchDarkly::DataSystem.custom
7 .initializers([
8 LaunchDarkly::DataSystem.polling_ds_builder.base_uri(relay_uri),
9 LaunchDarkly::DataSystem.polling_ds_builder,
10 ])
11 .synchronizers([
12 LaunchDarkly::DataSystem.streaming_ds_builder.base_uri(relay_uri),
13 LaunchDarkly::DataSystem.streaming_ds_builder,
14 LaunchDarkly::DataSystem.polling_ds_builder,
15 ])
16 .build
17)
18
19client = LaunchDarkly::LDClient.new("YOUR_SDK_KEY", config)

File-based bootstrap with live updates

Ruby SDK v8.12.0+
1require 'ldclient-rb'
2
3config = LaunchDarkly::Config.new(
4 data_system_config: LaunchDarkly::DataSystem.custom
5 .initializers([
6 LaunchDarkly::Integrations::FileData.data_source_v2(paths: ['flags.json']),
7 LaunchDarkly::DataSystem.polling_ds_builder,
8 ])
9 .synchronizers([
10 LaunchDarkly::DataSystem.streaming_ds_builder,
11 LaunchDarkly::DataSystem.polling_ds_builder,
12 ])
13 .build
14)
15
16client = LaunchDarkly::LDClient.new("YOUR_SDK_KEY", config)

To learn more, read LaunchDarkly::DataSystem. To learn more about additional configuration options, read DataSystem::ConfigBuilder.

Client-side SDKs

Client-side SDKs in data saving mode use the same data system pipeline as server-side SDKs, adapted to the lifecycle and connectivity characteristics of the client environment. SDKs may switch between connection modes automatically in response to application lifecycle events and network state changes. Some client-side SDKs use streaming when the application is active or in the foreground for real-time flag updates, and switch to polling or reduce activity when the application is backgrounded or hidden.

This feature is available in the following SDKs:

Android

Consider mobile update tails before shipping EAP code

Mobile applications have long update tails. Apps you ship today may remain installed on end-user devices for years. If you include the EAP version of the Android Client SDK in a production release, the EAP-era API surface and behaviors may persist in deployed apps long after data saving mode graduates to General Availability. Make sure your release timeline can tolerate shipping a non-stable API.

To enable data saving mode:

  1. Upgrade your Android Client SDK to version 5.13 or later.
  2. Request to join the Early Access Program. Wait to receive confirmation from LaunchDarkly that data saving mode is enabled for your account.
  3. Update your SDK configuration to enable the dataSystem configuration option.

Here’s how to enable the dataSystem configuration option:

Standard setup

1val config = LDConfig.Builder(AutoEnvAttributes.Enabled)
2 .mobileKey("example-mobile-key")
3 .dataSystem(Components.dataSystem())
4 .build()

We recommend the standard data system configuration for most customers. It uses a combination of streaming and polling to initialize the SDK, provide real time updates, and switch between streaming and polling automatically to provide redundancy.

Automatic mode switching

The Android Client SDK switches between connection modes automatically based on app lifecycle and network connectivity. You can disable automatic switching entirely, or selectively disable lifecycle-driven or network-driven switching.

To disable automatic switching entirely and keep the SDK in a single connection mode regardless of lifecycle or network changes:

1val config = LDConfig.Builder(AutoEnvAttributes.Enabled)
2 .mobileKey("example-mobile-key")
3 .dataSystem(
4 Components.dataSystem()
5 .automaticModeSwitching(AutomaticModeSwitchingConfig.disabled())
6 .foregroundConnectionMode(ConnectionMode.STREAMING))
7 .build()

To disable lifecycle-driven switching but continue switching modes when network connectivity changes:

1val config = LDConfig.Builder(AutoEnvAttributes.Enabled)
2 .mobileKey("example-mobile-key")
3 .dataSystem(
4 Components.dataSystem()
5 .automaticModeSwitching(
6 DataSystemComponents.automaticModeSwitching()
7 .lifecycle(false)
8 .network(true)
9 .build()))
10 .build()

To learn more, read Components.dataSystem(). To learn more about additional configuration options, read DataSystemBuilder.

JavaScript

To enable data saving mode:

  1. Upgrade your JavaScript SDK to version 4.9 or later.
  2. Request to join the Early Access Program. Wait to receive confirmation from LaunchDarkly that data saving mode is enabled for your account.
  3. Update your SDK configuration to enable the dataSystem configuration option.

Here’s how to enable the dataSystem configuration option:

Standard setup

JavaScript SDK v4.9+
1import { createClient } from '@launchdarkly/js-client-sdk';
2
3const client = createClient('example-client-side-id', context, {
4 dataSystem: {},
5});

We recommend the standard data system configuration for most customers. The JavaScript SDK opens a streaming connection for real-time flag updates, and falls back to polling when streaming is unavailable.

Set a fixed connection mode

To keep the SDK in a single connection mode instead of letting it manage the connection, use manual mode switching and set the initial connection mode:

JavaScript SDK v4.9+
1const client = createClient('example-client-side-id', context, {
2 dataSystem: {
3 automaticModeSwitching: { type: 'manual', initialConnectionMode: 'polling' },
4 },
5});

To learn more, read LDOptions.dataSystem.

React Native

Consider mobile update tails before shipping EAP code

Mobile applications have long update tails. Apps you ship today may remain installed on end-user devices for years. If you include the EAP version of the React Native SDK in a production release, the EAP-era API surface and behaviors may persist in deployed apps long after data saving mode graduates to General Availability. Make sure your release timeline can tolerate shipping a non-stable API.

To enable data saving mode:

  1. Upgrade your React Native SDK to version 10.19 or later.
  2. Request to join the Early Access Program. Wait to receive confirmation from LaunchDarkly that data saving mode is enabled for your account.
  3. Update your SDK configuration to enable the dataSystem configuration option.

Here’s how to enable the dataSystem configuration option:

Standard setup

React Native SDK v10.19+
1import { AutoEnvAttributes, ReactNativeLDClient } from '@launchdarkly/react-native-client-sdk';
2
3const client = new ReactNativeLDClient('example-mobile-key', AutoEnvAttributes.Enabled, {
4 dataSystem: {},
5});

We recommend the standard data system configuration for most customers. The React Native SDK uses streaming in the foreground for real-time flag updates and polling in the background, and switches between connection modes automatically as the app moves between the foreground and background.

Automatic mode switching

By default, the React Native SDK switches between connection modes automatically based on app lifecycle. To disable automatic switching entirely and keep the SDK in a single connection mode regardless of lifecycle changes:

React Native SDK v10.19+
1const client = new ReactNativeLDClient('example-mobile-key', AutoEnvAttributes.Enabled, {
2 dataSystem: {
3 automaticModeSwitching: false,
4 },
5});

To learn more, read LDOptions.dataSystem.

React Web

The React Web SDK is built on the JavaScript SDK, so it supports the same dataSystem configuration. Pass the option through the provider’s ldOptions.

To enable data saving mode:

  1. Upgrade your React Web SDK to version 4.2 or later.
  2. Request to join the Early Access Program. Wait to receive confirmation from LaunchDarkly that data saving mode is enabled for your account.
  3. Update your SDK configuration to enable the dataSystem configuration option.

Here’s how to enable the dataSystem configuration option:

Standard setup

React Web SDK v4.2+
1import { createLDReactProvider } from '@launchdarkly/react-sdk';
2
3export const LDReactProvider = createLDReactProvider('example-client-side-id', context, {
4 ldOptions: { dataSystem: {} },
5});

We recommend the standard data system configuration for most customers. The React Web SDK opens a streaming connection for real-time flag updates, and falls back to polling when streaming is unavailable.

Set a fixed connection mode

To keep the SDK in a single connection mode instead of letting it manage the connection, use manual mode switching and set the initial connection mode:

React Web SDK v4.2+
1export const LDReactProvider = createLDReactProvider('example-client-side-id', context, {
2 ldOptions: {
3 dataSystem: { automaticModeSwitching: { type: 'manual', initialConnectionMode: 'polling' } },
4 },
5});

To learn more, read LDReactClientOptions.