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

# Redis

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

> For the complete documentation index, see [llms.txt](/llms.txt). For the full documentation snapshot, see [llms-full.txt](/llms-full.txt).

## Overview

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 title="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](/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.
</Warning>

## 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 title="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 in the **Environments** list for your project. To learn more about key types, read [Keys](/sdk/concepts/client-side-server-side#keys).
</Note>

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)](#nodejs-server-side)
* [PHP](#php)
* [Python](#python)
* [Ruby](#ruby)

### .NET (server-side)

<Accordion title="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).

  <CodeGroup>
    ```csharp title="C#" 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);
    ```
  </CodeGroup>

  To learn more, read [`dotnet-server-sdk-redis`](https://github.com/launchdarkly/dotnet-server-sdk-redis).
</Accordion>

### C++ (server-side)

<Accordion title="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`.

  <CodeGroup>
    ```cpp title="C++ SDK v3.0 (native)" 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(*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)" 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, 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);

          LDClientConfig config;
          LDStatus status = LDClientConfigBuilder_Build(cfg_builder, &config);

          if (!LDStatus_Ok(status)) {
              // an error occurred, config is not valid
          }
    ```

    ```c title="C SDK v2.x (native)" theme={null}
          #include <launchdarkly/api.h>
          #include <launchdarkly/store/redis.h>

          struct LDConfig *config = LDConfigNew("YOUR_SDK_KEY");
          struct LDRedisConfig *redisConfig = LDRedisConfigNew();
          struct LDStoreInterface *store = LDStoreInterfaceRedisNew(redisConfig);

          LDConfigSetFeatureStoreBackend(config, store);
    ```
  </CodeGroup>
</Accordion>

### Erlang

The Erlang integration is part of the main SDK distribution.

<Accordion title="Expand Erlang code sample">
  <CodeGroup>
    ```erlang title="Erlang" 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" 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).
    ```
  </CodeGroup>
</Accordion>

### Go

<Accordion title="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`.

  <CodeGroup>
    ```go title="Go SDK v6.0" 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)
    ```
  </CodeGroup>

  To learn more, read [`go-server-sdk-redis-redigo`](https://pkg.go.dev/github.com/launchdarkly/go-server-sdk-redis-redigo).
</Accordion>

### Haskell

<Accordion title="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).

  <CodeGroup>
    ```haskell title="Haskell" 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:6379" }
              backend <- makeRedisStore $ redisConfigSetNamespace "my-key-prefix" $ makeRedisStoreConfig con

              let config = configSetStoreBackend backend $ makeConfig "YOUR_SDK_KEY"

              client <- makeClient config
    ```
  </CodeGroup>
</Accordion>

### Java

<Accordion title="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).

  <CodeGroup>
    ```java title="Java" 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);
    ```
  </CodeGroup>

  To learn more, read [`java-server-sdk-redis`](https://github.com/launchdarkly/java-server-sdk-redis).
</Accordion>

### Lua

<Accordion title="Expand Lua code sample">
  When you use Redis for storing data, you also need to include `launchdarkly_server_sdk_redis`:

  <CodeGroup>
    ```lua title="Lua SDK v2" 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)
    ```

    ```lua title="Lua SDK v1.x" theme={null}
          local l = require("launchdarkly_server_sdk")
          local r = require("launchdarkly_server_sdk_redis")

          local backend = r.makeStore({
              host   = "your-redis",
              port   = 6379,
              prefix = "your-key-prefix"
          })

          local c = l.clientInit({
              key                 = "YOUR_SDK_KEY",
              featureStoreBackend = backend
          )}
    ```
  </CodeGroup>
</Accordion>

### Node.js (server-side)

<Accordion title="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.

  <CodeGroup>
    ```js title="Node.js SDK v8.x (JavaScript)" 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)" 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);
    ```

    ```js title="Node.js SDK v7.x and earlier (JavaScript)" theme={null}
          const ld = require('launchdarkly-node-server-sdk');
          const RedisFeatureStore = require('launchdarkly-node-server-sdk-redis');

          const redisOpts = {
            url: 'redis://your-redis:6379'
          };
          const store = RedisFeatureStore(redisOpts, 30, 'your-key-prefix');

          const options = {
            featureStore: store
          };
          const client = ld.init(sdkKey, options);
    ```

    ```ts title="Node.js SDK v7.x and earlier (TypeScript)" theme={null}
          import { LDOptions, init } 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: LDOptions = {
            featureStore: store,
          };
          const client = init('YOUR_SDK_KEY', options);
    ```
  </CodeGroup>
</Accordion>

### PHP

<Accordion title="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:

  <CodeGroup>
    ```php title="PHP SDK v6.4+" 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" 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
          ]);
    ```
  </CodeGroup>

  To use the `phpredis` integration:

  <CodeGroup>
    ```php title="PHP" theme={null}
          $fr = LaunchDarkly\Integrations\PHPRedis::featureRequester([
              'redis_host' => 'my-redis',
              'redis_port' => 6379,
              'redis_prefix' => 'my-key-prefix'
          ]);
          $client = new LaunchDarkly\LDClient("YOUR_SDK_KEY", [
              'feature_requester' => $fr
          ]);
    ```
  </CodeGroup>

  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).
</Accordion>

### Python

<Accordion title="Expand Python code sample">
  The Python integration is part of the main SDK distribution, but you must also install the package `redis`.

  <CodeGroup>
    ```python title="Python" 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)
    ```
  </CodeGroup>
</Accordion>

### Ruby

<Accordion title="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`.

  <CodeGroup>
    ```ruby title="Ruby" 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::Client.new(sdk_key, config)
    ```
  </CodeGroup>
</Accordion>
