> ## Documentation Index
> Fetch the complete documentation index at: https://launchdarkly.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Redis

<View title="Developer" />

<View title="Federal docs" />

<View title="EU docs" />

This topic explains how to use the SDK Redis integration as a persistent feature store.

Many of our server-side SDKs support Redis. The available options are slightly different in each language, but you can always specify the following:

* The Redis host address, which defaults to `localhost:6379`
* A prefix string to add to all keys used by the store, to avoid collisions in case the database is also being used for some other purpose
* The length of time that recently read or updated data should be cached in memory

> [!WARNING]
>
> **Supported Redis configurations**
>
> The LaunchDarkly SDKs use third-party open source libraries to connect to Redis. Not all of these have the same level of support for advanced Redis configurations. Specifically, most of the SDKs and the [Relay Proxy](/docs/sdk/relay-proxy) do not support connecting to a Redis cluster or using Redis Sentinel for service discovery.
>
> To learn more, read the documentation for the individual SDKs below, or their Redis integration add-on libraries for SDKs that do not have this integration built in.

## How the SDKs store data in Redis

The Redis integrations for all LaunchDarkly server-side SDKs use the same conventions, so that SDK instances and Relay Proxy instances sharing a single Redis store can interoperate correctly.

The storage schema is as follows:

* There is always a "prefix" string that provides a namespace for the overall data set. If you do not specify a prefix in your configuration, it is `launchdarkly`. If you are using a persistent store integration, it must be the client-side ID for the environment.
* For each type of data that the SDK can store, there is a hash whose key is `PREFIX:TYPE`. `PREFIX` is the configured prefix string. `TYPE` denotes the type of data such as `features` and `segments`.
* Within each hash, there is one field per data item. For instance, the hash `PREFIX:features` has one field per feature flag. The field name is the unique key of the item, such as the flag key for a feature flag, and the value is a serialized representation of that item, in a format that is determined by the SDK.
* An additional key, `PREFIX:$inited`, is created with an arbitrary value when the SDK stores a full set of feature flag data. This allows a new SDK instance to check whether there is already a valid data set that was stored earlier.
* The SDK may use additional keys starting with the `PREFIX` string, so you should not assume that the `TYPE` values mentioned above and `$inited` are the only possible keys. The SDK never adds, modifies, or removes any keys in Redis other than ones starting with the `PREFIX`, so it is safe to share a Redis instance that is also being used for other purposes.

## Server-side SDKs

In the following examples, the Redis feature store is set to use a host address of `my-redis:6379`, a prefix string of `"my-key-prefix"`, and a cache TTL of 15 or 30 seconds, depending on the SDK.

> [!NOTE]
>
> **Using a persistent store for segments requires a specific key prefix**
>
> If you are using a persistent store integration, the value of the key prefix for the persistent store must be the client-side ID of your environment.
>
> Your environment's client-side ID is available on the **SDK keys** page under **Settings**. To learn more about key types, read [Keys](/docs/sdk/concepts/client-side-server-side#keys-and-credentials).

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

* [.NET (server-side)](#net-server-side)
* [C++ (server-side)](#c++-server-side)
* [Erlang](#erlang)
* [Go](#go)
* [Haskell](#haskell)
* [Java](#java)
* [Lua](#lua)
* [Node.js (server-side)](#node-js-server-side)
* [PHP](#php)
* [Python](#python)
* [Ruby](#ruby)

### .NET (server-side)

> **Expand .NET (server-side) code sample**
>
> To use Redis with the .NET SDK you must install an additional package named [`LaunchDarkly.ServerSdk.Redis`](https://github.com/launchdarkly/dotnet-server-sdk-redis).
>
> ```csharp title="C#" lines wrap theme={null}
> using LaunchDarkly.Sdk.Server;
> using LaunchDarkly.Sdk.Server.Integrations;
> var config = Configuration.Builder(sdkKey)
>     .DataStore(
>         Components.PersistentDataStore(
>             Redis.DataStore()
>                 .HostAndPort("my-redis", 6379)
>                 .Prefix("my-key-prefix")
>         ).CacheSeconds(30)
>     )
>     .Build();
> var client = new LdClient(config);
> ```
>
> To learn more, read [`dotnet-server-sdk-redis`](https://github.com/launchdarkly/dotnet-server-sdk-redis).

### C++ (server-side)

> **Expand C++ (server-side) code sample**
>
> The C++ integration is part of the main SDK distribution, but is disabled by default in order to avoid bringing in unnecessary dependencies ([`redis++`](https://github.com/sewenew/redis-plus-plus), a wrapper for [`hiredis`](https://github.com/redis/hiredis)).
>
> To ensure the integration header and library are available for your build, set the CMake option `LD_BUILD_REDIS_SUPPORT=ON`.
>
> ```cpp title="C++ SDK v3.0 (native)" maxLines=0 expandable lines wrap theme={null}
> // Make sure to include the redis source's header.
> #include <launchdarkly/server_side/integrations/redis/redis_source.hpp>
>
> using namespace launchdarkly::server_side;
>
> using LazyLoad = config::builders::LazyLoadBuilder;
>
> ConfigBuilder config_builder(sdk_key);
>
> auto redis_source = integrations::RedisDataSource::Create("redis://localhost:6379", "my-key-prefix");
>
> if (!redis_source) {
>     /* redis config is invalid, cannot proceed */
> }
>
> config_builder.DataSystem().Method(
>     LazyLoad().Source(std::move(*redis_source)).CacheRefresh(std::chrono::seconds(15))
> );
>
> auto config = config_builder.Build();
> if (!config) {
>     /* an error occurred, config is not valid */
> }
> ```
>
> ```c title="C++ SDK v3.0 (C binding)" maxLines=0 expandable lines wrap theme={null}
> // Stack allocate the result struct, which will hold the result pointer or
> // an error message.
> struct LDServerLazyLoadRedisResult result;
>
> // Create the Redis source, passing in arguments for the URI, prefix, and
> // pointer to the result.
> if (!LDServerLazyLoadRedisSource_New("redis://localhost:6379", "my-key-prefix",
> &result)) {
>     // Redis config is invalid, cannot proceed.
>     // Error message is stored in result.error_message.
> }
>
> // Create a builder for the Lazy Load data system.
> LDServerLazyLoadBuilder lazy_builder = LDServerLazyLoadBuilder_New();
>
> // Pass the Redis source pointer into it.
> LDServerLazyLoadBuilder_SourcePtr(lazy_builder,
>                                   (LDServerLazyLoadSourcePtr)result.source);
>
> // Create a standard server-side SDK configuration builder.
> LDServerConfigBuilder cfg_builder = LDServerConfigBuilder_New("YOUR_SDK_KEY");
>
> // Tell the SDK config builder to use the Lazy Load system that was just
> // configured.
> LDServerConfigBuilder_DataSystem_LazyLoad(cfg_builder, lazy_builder);
>
> LDServerConfig config;
> LDStatus status = LDServerConfigBuilder_Build(cfg_builder, &config);
>
> if (!LDStatus_Ok(status)) {
>     // an error occurred, config is not valid
> }
> ```

### Erlang

The Erlang integration is part of the main SDK distribution.

> **Expand Erlang code sample**
>
> ```erlang title="Erlang" lines wrap theme={null}
> LdOptions = #{
>   redis_host     => "redis",
>   redis_port     => "6379",
>   redis_prefix   => "default",
>   feature_store  => ldclient_storage_redis,
>   cache_ttl      => 15
> },
> ldclient:start_instance("YOUR_SDK_KEY", LdOptions).
> ```
>
> ```erlang title="Erlang with TLS" lines wrap theme={null}
> LdOptions = #{
>   redis_host     => "redis",
>   redis_port     => "6379",
>   redis_prefix   => "default",
>   %% Exact configuration will vary based on the Redis configuration.
>   %% These parameters are forwarded to the eredis libraries `tls` option.
>   redis_tls      => [{cacertfile, "ca.crt"},
>                      {certfile,   "client.crt"},
>                      {keyfile,    "client.key"}],
>   feature_store  => ldclient_storage_redis,
>   cache_ttl      => 15
> },
> ldclient:start_instance("YOUR_SDK_KEY", LdOptions).
> ```

### Go

> **Expand Go code sample**
>
> The Go integration is in [`github.com/launchdarkly/go-server-sdk-redis-redigo`](https://github.com/launchdarkly/go-server-sdk-redis-redigo) for 5.0.0 or higher of the SDK. In earlier SDK versions, it is in the main SDK distribution as the subpackage `redis`.
>
> ```go title="Go SDK v6+" lines wrap theme={null}
> import (
>     "time"
>
>     ld "github.com/launchdarkly/go-server-sdk/v6"
>     "github.com/launchdarkly/go-server-sdk/v6/ldcomponents"
>     ldredis "github.com/launchdarkly/go-server-sdk-redis-redigo"
> )
>
> var config ld.Config
> config.DataStore = ldcomponents.PersistentDataStore(
>     ldredis.DataStore().
>         HostAndPort("my-redis", 6379).
>         Prefix("my-key-prefix"),
> ).CacheSeconds(30)
> client, _ := ld.MakeCustomClient(sdkKey, config, 5*time.Second)
> ```
>
> To learn more, read [`go-server-sdk-redis-redigo`](https://pkg.go.dev/github.com/launchdarkly/go-server-sdk-redis-redigo).

### Haskell

> **Expand Haskell code sample**
>
> To use Redis with the Haskell SDK, you must install an additional package.
>
> If you are working with version 4.0 of the Haskell SDK, use [`launchdarkly-server-sdk-redis-hedis`](https://hackage.haskell.org/package/launchdarkly-server-sdk-redis-hedis), which is in a separate repository. It is compatible with version 4.0 and higher of the Haskell SDK.
>
> If you are working with versions 3.x and earlier, use [`launchdarkly-server-sdk-redis`](https://github.com/launchdarkly/haskell-server-sdk/tree/3.x/stores/launchdarkly-server-sdk-redis).
>
> ```haskell title="Haskell" lines wrap theme={null}
> import qualified Database.Redis as               R
> import           LaunchDarkly.Server
> import           LaunchDarkly.Server.Store.Redis
>
> main = do
>     con <- R.checkedConnect R.defaultConnectInfo { R.connectHost = "my-redis", R.connectPort = R.PortNumber 6379 }
>     backend <- makeRedisStore $ redisConfigSetNamespace "my-key-prefix" $ makeRedisStoreConfig con
>
>     let config = configSetStoreBackend (Just backend) $ makeConfig "YOUR_SDK_KEY"
>
>     client <- makeClient config
> ```

### Java

> **Expand Java code sample**
>
> You must install the additional package [`com.launchdarkly.launchdarkly-java-server-sdk-redis-store`](https://github.com/launchdarkly/java-server-sdk-redis).
>
> ```java title="Java" lines wrap theme={null}
> import com.launchdarkly.sdk.server.*;
> import com.launchdarkly.sdk.server.integrations.*;
>
> LDConfig config = new LDConfig.Builder()
>   .dataStore(
>     Components.persistentDataStore(
>       Redis.dataStore().uri(URI.create("redis://my-redis:6379"))
>         .prefix("my-key-prefix")
>     ).cacheSeconds(30)
>   )
>   .build();
> LDClient client = new LDClient(sdkKey, config);
> ```
>
> To learn more, read [`java-server-sdk-redis`](https://github.com/launchdarkly/java-server-sdk-redis).

### Lua

> **Expand Lua code sample**
>
> When you use Redis for storing data, you also need to include `launchdarkly_server_sdk_redis`:
>
> ```lua title="Lua SDK v2" lines wrap theme={null}
> local l = require("launchdarkly_server_sdk")
> local r = require("launchdarkly_server_sdk_redis")
>
> local redis = r.makeRedisSource("redis://localhost:6379", "your-key-prefix")
> local config = {
>     dataSystem = {
>         lazyLoad = {
>             source = redis
>         }
>     }
> }
>
> local c = l.clientInit("YOUR_SDK_KEY", 1000, config)
> ```

### Node.js (server-side)

> **Expand Node.js (server-side) code sample**
>
> In version 8.0.0 and higher of the Node.js SDK, you must install the additional package [`@launchdarkly/node-server-sdk-redis`](https://github.com/launchdarkly/js-core/tree/main/packages/store/node-server-sdk-redis). In versions 6.0.0-7.x of the Node.js SDK, you must install the additional package [`launchdarkly-node-server-sdk-redis`](https://github.com/launchdarkly/node-server-sdk-redis).
>
> In version 3.0 and higher of the Node.js SDK Redis integration, the [`ioredis`](https://github.com/redis/ioredis) package is used for Redis operations. In versions 2.x of the Node.js SDK Redis integration, the [`redis`](https://github.com/redis/node-redis) package is used for Redis operations.
>
> ```js title="Node.js SDK v8.x+ (JavaScript)" lines wrap theme={null}
> const ld = require('@launchdarkly/node-server-sdk');
> const { RedisFeatureStore } = require('@launchdarkly/node-server-sdk-redis');
>
> const store = RedisFeatureStore({
>     redisOpts: { host: 'redis-host', port: 6379 },
>     prefix: 'your-key-prefix',
>     cacheTTL: 30,
> });
>
> const options = {
>   featureStore: store
> };
> const client = ld.init(sdkKey, options);
> ```
>
> ```ts title="Node.js SDK v8.x+ (TypeScript)" lines wrap theme={null}
> import * as ld from '@launchdarkly/node-server-sdk';
> import { RedisFeatureStore } from '@launchdarkly/node-server-sdk-redis';
>
> const store = RedisFeatureStore({
>     redisOpts: { host: 'redis-host', port: 6379 },
>     prefix: 'your-key-prefix',
>     cacheTTL: 30,
> });
>
> const options: ld.LDOptions = {
>   featureStore: store,
> };
> const client = ld.init('YOUR_SDK_KEY', options);
> ```

### PHP

> **Expand PHP code sample**
>
> There are two Redis integrations for the PHP SDK. One uses the [Predis](https://github.com/predis/predis) package, which can be used in any PHP environment. The other uses the more efficient [`phpredis`](https://github.com/phpredis/phpredis) extension, which must be installed in PHP itself. Both of these integrations are in v2, which is compatible with the PHP SDK v6.4 and later.
>
> In version 4.0 and higher of the PHP SDK, you must add a package to your application's Composer dependencies to use one of these two integrations:
>
> * For the Predis integration, add `launchdarkly/server-sdk-redis-predis`.
> * For the `phpredis` integration, add `launchdarkly/server-sdk-redis-phpredis`.
>
> To use the Predis integration:
>
> ```php title="PHP SDK v6.4+" lines wrap theme={null}
> $redisClient = new Predis\Client([
>     'host' => 'my-redis',
>     'port' => 6379
> ]);
>
> $fr = LaunchDarkly\Integrations\Redis::featureRequester($redisClient, ['prefix' => 'my-key-prefix']);
> $client = new LaunchDarkly\LDClient("YOUR_SDK_KEY", [
>     'feature_requester' => $fr
> ]);
> ```
>
> ```php title="PHP SDK v6.3 and earlier" lines wrap theme={null}
> $fr = LaunchDarkly\Integrations\Redis::featureRequester([
>     'redis_host' => 'my-redis',
>     'redis_port' => 6379,
>     'redis_prefix' => 'my-key-prefix'
> ]);
> $client = new LaunchDarkly\LDClient("YOUR_SDK_KEY", [
>     'feature_requester' => $fr
> ]);
> ```
>
> To use the `phpredis` integration:
>
> ```php title="PHP" lines wrap theme={null}
> $redisClient = new Redis();
> $redisClient->connect('my-redis', 6379);
>
> $fr = LaunchDarkly\Integrations\PHPRedis::featureRequester($redisClient, ['prefix' => 'my-key-prefix']);
> $client = new LaunchDarkly\LDClient("YOUR_SDK_KEY", [
>     'feature_requester' => $fr
> ]);
> ```
>
> To learn more, read [`php-server-sdk-redis-predis`](https://github.com/launchdarkly/php-server-sdk-redis-predis) or [`php-server-sdk-redis-phpredis`](https://github.com/launchdarkly/php-server-sdk-redis-phpredis).

### Python

> **Expand Python code sample**
>
> The Python integration is part of the main SDK distribution, but you must also install the package `redis`.
>
> ```python title="Python" lines wrap theme={null}
> import ldclient
> from ldclient.config import Config
> from ldclient.feature_store import CacheConfig
> from ldclient.integrations import Redis
>
> store = Redis.new_feature_store(url='redis://my-redis:6379',
>     prefix='my-key-prefix', caching=CacheConfig(expiration=30))
>
> config = Config(feature_store=store)
> ldclient.set_config(config)
> ```

### Ruby

> **Expand Ruby code sample**
>
> The Ruby integration is part of the main SDK distribution, but you must also install the gems `redis` and `connection_pool`.
>
> ```ruby title="Ruby" lines wrap theme={null}
> require 'ldclient-rb'
>
> store = LaunchDarkly::Integrations::Redis.new_feature_store(
>   redis_url: 'redis://my-redis:6379',
>   prefix: 'my-key-prefix',
>   expiration: 30
> )
>
> config = LaunchDarkly::Config.new(
>   feature_store: store
> )
> client = LaunchDarkly::LDClient.new(sdk_key, config)
> ```
