No results for ""
EXPAND ALL
  • Home
  • API docs

Storing data

Read time: 9 minutes
Last edited: May 30, 2024

Overview

This topic explains which external databases each server-side SDK can use to store flag data.

By default, all our SDKs work with an in-memory feature store. This feature store requires no additional configuration. However, data in in-memory feature stores are not persistent. This means when you restart your application, your SDK reloads the entire store's contents.

Persistent feature stores solve this problem by persisting their data so that they can be used across application restarts.

Using external databases as persistent feature stores

By default, LaunchDarkly's server-side SDKs connect to LaunchDarkly and receive feature flag data, store the flags in local memory, and update them when prompted to by LaunchDarkly. This collection of last known flag data is cached in the "feature store" or "data store."

To learn more, read Persistent data stores.

Alternatively, you can configure an external database to act as a feature store. The SDKs in this topic can use one or more of these three caching options to hold their flag data:

  • Consul
  • DynamoDB
  • Redis

Whichever database you use, there are two ways to use it:

In both configurations, you can control when the SDK checks the database, as opposed to in-memory caching, using the cache time-to-live (TTL) configuration option for your SDK. There is a tradeoff here that will be different for each customer. Most customers find that it's generally unacceptable from a performance standpoint to read from the database on every flag evaluation. If you prefer faster evaluations and can accept some stale data, you can have the SDK check the in-memory caching more frequently. If you prefer fresher data and can accept slower evaluations, you can have the SDK check the database more frequently.

Using a persistent feature store while still connecting to LaunchDarkly

In this configuration, the SDK receives feature flag data from LaunchDarkly and puts it in the feature store. The only difference is that the store is in a database.

When flags are evaluated, the SDK checks the database to get the latest flag state, usually with some form of in-memory caching. If you have a persistent feature store that has already been populated, the SDK can still evaluate flags using the last known flag state from the store until newer data is available from LaunchDarkly.

To set up this configuration, most people create some kind of object for the specific type of database and put it in the client configuration's feature store property. In PHP, this property is called the "feature requester."

If there are multiple instances of your application configured in this way with the same database, the same data gets written to the database multiple times, because each instance receives feature flags from LaunchDarkly. This is harmless, but it is inefficient, so you may want to use a persistent feature store without connecting to LaunchDarkly, as described below.

Using a persistent feature store without connecting to LaunchDarkly

This is similar to the previous configuration: When flags are evaluated, the SDK checks the database to get the latest flag state, usually with some form of in-memory caching. However, in this configuration the SDK does not connect to LaunchDarkly at all. Instead, it relies on some other process which does have a LaunchDarkly connection to write the latest flag data to the database, where the SDK will then read it.

The other process could be the Relay Proxy in offline or daemon mode, or any other application that creates an SDK client with the same persistent store. To learn more about the Relay Proxy, read The Relay Proxy.

The Relay Proxy is also known as the LaunchDarkly Daemon, so some versions of the SDKs refer to this mode as "LDD mode." Creating the client is the same as above in terms of specifying the persistent store, but you must also add an option to make the SDK not connect to LaunchDarkly.

Server-side SDKs

This feature is available in the following server-side SDKs:

.NET (server-side)

Expand .NET (server-side) code sample

The .NET SDK can use Consul, DynamoDB, or Redis to hold flag data.

To use a persistent feature store while connecting to LaunchDarkly:

using LaunchDarkly.Sdk.Server;
using LaunchDarkly.Sdk.Server.Integrations;
var config = Configuration.Builder(sdkKey)
.DataStore(
Components.PersistentDataStore(
SomeDatabaseName.DataStore()
)
)
.Build();

To learn more, read ConfigurationBuilder.DataStore.

To use a persistent feature store without connecting to LaunchDarkly, use the DataStore builder method as above, and then use Components.ExternalUpdatesOnly to configure daemon mode. To learn more, read Using daemon mode.

C++ (server-side)

Expand C++ (server-side) code sample

The C++ SDK can use Redis to hold flag data.

In the C++ SDK v3.0, you cannot use a persistent feature store while connecting to LaunchDarkly.

To use a persistent feature store without having the SDK connect to LaunchDarkly, use the LazyLoadBuilder. The SDK reads flag data from the persistent store lazily, in the background.

Here's how:

using LazyLoad = server_side::config::builders::LazyLoadBuilder;
auto config_builder = server_side::ConfigBuilder(sdk_key);
auto some_source = YourDatabaseIntegration();
config_builder.DataSystem().Method(
LazyLoad().Source(some_source)
);
auto config = config_builder.Build();
if (!config) {
/* an error occurred, config is not valid */
}

To learn more, read Using daemon mode and LazyLoadBuilder.

Erlang

Expand Erlang code sample

The Erlang SDK can use Redis to hold flag data.

To use a persistent feature store while connecting to LaunchDarkly:

LdOptions = #{
feature_store => your_feature_store
},
ldclient:start_instance("sdk-key-123abc", LdOptions).

To use a persistent feature store without connecting to LaunchDarkly, set the feature_store property as above, and then set the use_ldd option to configure daemon mode. To learn more, read Using daemon mode.

Go

Expand Go code sample

The Go SDK can use Consul, DynamoDB, or Redis to hold flag data.

To use a persistent feature store while connecting to LaunchDarkly:

import (
"time"
ld "github.com/launchdarkly/go-server-sdk/v6"
"github.com/launchdarkly/go-server-sdk/v6/ldcomponents"
examplepackage "github.com/launchdarkly/go-server-sdk-some-example-database"
)
var config ld.Config
config.DataStore = ldcomponents.PersistentDataStore(
examplepackage.DataStore().SomeStoreOptions(),
)
client, _ := ld.MakeCustomClient(sdkKey, config, 5*time.Second)

To learn more, read PersistentDataStore.

To use a persistent feature store without connecting to LaunchDarkly, use PersistentDataStore() as above, and then use ExternalUpdatesOnly() to configure daemon mode. To learn more, read Using daemon mode.

Haskell

Expand Haskell code sample

The Haskell SDK can use Redis to hold flag data.

To use a persistent feature store while connecting to LaunchDarkly:

import LaunchDarkly.Server
main = do
backend <- makeYourBackendInterface
let config = configSetStoreBackend backend $ makeConfig "sdk-key-123abc"
client <- makeClient config

To use a persistent feature store without connecting to LaunchDarkly, use configSetStoreBackend as above, and then use configSetUseLdd to configure daemon mode. To learn more, read Using daemon mode.

Java

Expand Java code sample

The Java SDK can use Consul, DynamoDB, or Redis to hold flag data.

To use a persistent feature store while connecting to LaunchDarkly:

import com.launchdarkly.sdk.server.*;
import com.launchdarkly.sdk.server.integrations.*;
LDConfig config = new LDConfig.Builder()
.dataStore(
Components.persistentDataStore(
SomeDatabaseName.dataStore(storeOptions)
)
)
.build();
LDClient client = new LDClient(sdkKey, config);

To learn more, read Components.persistentDataStore.

To use a persistent feature store without connecting to LaunchDarkly, use persistentDataStore as above, and then use externalUpdatesOnly to configure daemon mode. To learn more, read Using daemon mode.

Lua

Expand Lua code sample

The Lua SDK can use Redis to hold flag data. The module launchdarkly_server_sdk_redis caches the feature flag data.

In the Lua SDK v2, you cannot use a persistent feature store while connecting to LaunchDarkly.

To use a persistent feature store without having the SDK connect to LaunchDarkly, specify a lazyLoad data source. The SDK reads flag data from the persistent store lazily, in the background.

Here's how:

local config = {
dataSystem = {
lazyLoad = {
source = makeYourSource()
}
}
}

In the Lua SDK v1, you can use a feature store while connecting to LaunchDarkly.

Expand Lua code sample for older versions

To use a persistent feature store while connecting to LaunchDarkly:

local l = require("launchdarkly_server_sdk")
local backend = makeYourBackendInterface()
local c = l.clientInit({
key = "sdk-key-123abc",
featureStoreBackend = backend
)}

To learn more, read Using daemon mode.

Node.js (server-side)

Expand Node.js (server-side) code sample

The Node.js SDK can use Consul, DynamoDB, or Redis to hold flag data.

To use a persistent feature store while connecting to LaunchDarkly:

const ld = require('@launchdarkly/node-server-sdk');
const store = SomeKindOfFeatureStore(storeOptions);
const options = {
featureStore: store
};
const client = ld.init('sdk-key-123abc', options);

To use a persistent feature store without connecting to LaunchDarkly, set the featureStore property as above, and then set the useLdd property to configure daemon mode. To learn more, read Using daemon mode.

PHP

Expand PHP code sample

The PHP SDK can use Consul, DynamoDB, or Redis to get flag data.

Unlike other server-side SDKs, the PHP SDK cannot connect to LaunchDarkly while using a database as a backing store. It can only read from a database that has been populated by the Relay Proxy, or by another application that uses a server-side LaunchDarkly SDK. To learn more, read Using daemon mode.

Another difference from other SDKs is that the PHP SDK does not have an in-memory cache for database queries. This is because in PHP, the entire in-memory application state is normally discarded after each request. Therefore, code examples for PHP do not include a cache TTL parameter.

To read from a persistent feature store without connecting to LaunchDarkly:

$client = new LaunchDarkly\LDClient("sdk-key-123abc", [
'feature_requester' => LaunchDarkly\Integrations\NameOfDatabase::featureRequester()
]);

Prior to version 4.0, the database integrations were included in the main PHP SDK package. Starting in version 4.0, they are in separate packages.

Python

Expand Python code sample

The Python SDK can use Consul, DynamoDB, or Redis to hold flag data.

To use a persistent feature store while connecting to LaunchDarkly:

import ldclient
from ldclient.config import Config
store = SomeKindOfFeatureStore(store_options)
config = Config(feature_store=store)
ldclient.set_config(config)

To use a persistent feature store without connecting to LaunchDarkly, set the feature_store property as above, and then set the use_ldd property to configure daemon mode. To learn more, read Using daemon mode.

Ruby

Expand Ruby code sample

The Ruby SDK can use Consul, DynamoDB, or Redis to hold flag data.

These adapters are implemented in the LaunchDarkly::Integrations::Redis, LaunchDarkly::Integrations::DynamoDB, and LaunchDarkly::Integrations::Consul modules. To use them, call the new_feature_store method in the module, and put the returned object in the feature_store property of your client configuration.

To use a persistent feature store while connecting to LaunchDarkly:

require 'ldclient-rb'
store = SomeKindOfFeatureStore.new(storeOptions)
config = LaunchDarkly::Config.new(
feature_store: store
)
client = LaunchDarkly::Client.new(sdk_key, config)

To use a persistent feature store without connecting to LaunchDarkly, set the feature_store property as above, and then set the use_ldd property to configure daemon mode. To learn more, read Using daemon mode.