On this page

Server Data Stores / Data Adapter

Configure a custom data store adapter in Statsig server SDKs to cache rule configurations in Redis, DynamoDB, or another store you control.

A common question when configuring Statsig is how to handle potential points of failure. For example, if there is a Statsig API outage, can your integration continue to function?

Yes. Your server SDK continues to operate normally, serving the most recent set of known values in response to calls like checkGate, getConfig, getExperiment, and getLayer. After the API recovers, your SDK automatically re-fetches the most up-to-date version of your project.

Starting a new server or SDK instance while Statsig is down is a different scenario. The DataAdapter/DataStore addresses this case.

DataAdapter (or DataStore)

DataAdapters let you plug in your own storage solution as a cache that the Statsig Server SDKs use to load your project configurations (all experiments, configs, gates, and their targeting and allocation rules). Key use cases include reducing dependency on Statsig servers for initialization, improving initialization time by loading config from a local data store, and minimizing network I/O. DataAdapters implement a simple API: initialize, get, set, and shutdown.

In most cases, your web servers should only implement the read path (get). Leaving the write path (set) empty is the best practice. If every SDK instance writes to the store on every update, this creates unnecessary contention and duplication.

Instead, you should have a single source of truth that keeps your datastore up-to-date:

  • Run a separate out-of-band service that implements the SDK and is responsible for writing updates into the datastore using set.
  • Or, use a cron job / periodic job to fetch the config from the Statsig CDN endpoint and update your datastore under the correct cache keys (statsig.cache, statsig.id_lists, and statsig.id_lists::{list_name}).

The Statsig SDK already handles this refresh logic by default, so separating read and write responsibilities is the cleanest and most reliable pattern.

Data adapter logic

  • When the Statsig SDK is initialized with a DataAdapter, it first attempts to load config using DataAdapter.get.
    • If the entry exists, the SDK uses it.
    • If the entry doesn't exist and localMode isn't enabled, the SDK fetches the config from Statsig servers and (if you have a writer service) persists it using DataAdapter.set.
  • After initialization, the SDK continues to poll Statsig servers for updates and saves them back to your data store when available (if you have implemented set and designated a writer service).
  • If the SDK client is initialized with localMode=true, this will disable all network fetches from Statsig.
  • The cache keys used to be:
    • statsig.cache → config specs
    • statsig.id_lists → lookup of id lists
    • statsig.id_lists::{list_name} → actual id list values
  • but in the latest node and server core sdks, the format has changed:
    • statsig|{path}|{format}|{hashedSDKKey} where path is /v1/download_config_specs or /v1/get_id_lists, format is plain_text, and the djb2 has of the sdk key is the last bit
    • the SDK will handle this for you, reach out if you are trying to recreate this path yourself to double check

Most DataAdapters are used only for the initialize path for getting a project definition.

At the time of this writing, only Node.js, Ruby, Go, Java and .NET support polling for updates.
If you're interested in using a DataAdapter as the source of truth indefinitely, reach out in the Slack community and let us know which language this would be useful for!

For information on your specific SDK language, go to the language-specific docs in the left-hand column.

Was this helpful?