On this page

C++ Server SDK

Statsig's Next-gen Cpp Server SDK built in our [Server Core](/server-core) framework

Setup the SDK

  1. Install the SDK

    Installation

    All core logic is written in Rust. Statsig attaches prebuilt binaries as assets with each release, so a Rust environment isn't required. The CMakeLists.txt file handles the build configuration.

    If you encounter any installation or build issues, contact us.

    CMake
    FetchContent_Declare(
        Statsig
        GIT_REPOSITORY    https://github.com/statsig-io/statsig-cpp-core.git
        GIT_TAG           0.12.2-rc.1 
    )
    FetchContent_MakeAvailable(Statsig)
    
    target_include_directories(CppApp PRIVATE ${statsig_SOURCE_DIR}/include)
    target_include_directories(CppApp PRIVATE ${statsig_SOURCE_DIR}/src)
    
    target_link_libraries(CppApp PRIVATE Statsig)
    
  2. Initialize the SDK

    After installation, initialize the SDK using a Server Secret Key from the Statsig console.

    Server Secret Keys should always be kept private. If you expose one, you can disable and recreate it in the Statsig console.

    An optional options parameter accepts a StatsigOptions object to customize the SDK.

    cpp
    #include <statsig/statsig.h>
    
    statsig_cpp_core::StatsigOptionsBuilder optionsBuilder;
    optionsBuilder.environment = "development";
    optionsBuilder.specs_url = api_v2 + "/download_config_specs";
    optionsBuilder.log_event_url = api + "/log_event";
    optionsBuilder.id_lists_url = api + "/get_id_lists";
    statsig_cpp_core::StatsigOptions options = optionsBuilder.build();
    Statsig statsig("server-secret-key", options);
    statsig.initializeBlocking().wait();
    
    
    initialize performs a network request. After initializeBlocking completes, virtually all SDK operations are synchronous (refer to Evaluating Feature Gates in the Statsig SDK). The SDK fetches updates from Statsig in the background, independent of your API calls.

Tested platforms

The upstream Statsig docs source doesn't yet include a testedPlatforms snippet for C++ Core. Use the statsig-cpp-core release assets and your target Linux distribution when validating Docker images. Add a tested-platforms table here when the snippet is published upstream.

Working with the SDK

Checking a Feature Flag/Gate

After the SDK is initialized, you can fetch a Feature Gate. Feature Gates create logic branches in code that you can roll out to different users from the Statsig Console. Gates are CLOSED or OFF (equivalent to return false;) by default.All APIs require a user object (refer to Statsig user). To check a gate for a user:
cpp

if (statsig.checkGate(user, "a_gate")) {
    // Gate is on, enable new feature
} else {
    // Gate is off
}

You can also disable exposure logging for this evaluation:

cpp
FeatureGateEvaluationOptions options;
options.disable_exposure_logging = true;
bool gateValue = statsig.check_gate(user, "a_gate", options);

Reading a Dynamic Config

Feature Gates are useful for simple on/off switches with optional user targeting. To send different values (strings, numbers, etc.) to clients based on user attributes such as country, use Dynamic Configs. The API is similar to Feature Gates, but returns a JSON object from which you can retrieve typed parameters. For example:
cpp
// Get a dynamic config for a specific user
DynamicConfig config = statsig.getDynamicConfig(user, "a_config");

// Access config values (We will provide accessors)
std::string product_name = config.value.get("product_name", "Awesome Product v1");
double price = config.value.get("price", 10.0);


// Access evaluation details such as rule id 
statsig_cpp_core::EvaluationDetails detail = config.details;
std::cout << config.rule_id << std::endl;  // The ID of the rule that served this config
std::cout << config.id_type << std::endl;  // The type of the evaluation (experiment, config, etc)

// Advanced Usage:
// You can disable exposure logging for this specific check
DynamicConfigEvaluationOptions options;
options.disable_exposure_logging = true;
config = statsig.getDynamicConfig(user, "a_config", options);

Getting a Layer/Experiment

Layers/Experiments let you run A/B/n experiments. Two APIs are available, but layers are recommended because layers make parameters reusable and support mutually exclusive experiments.
cpp
// Get a experiment for a specific user
statsig_cpp_core::Experiment exp = statsig.getExpriment(user, "an_experiment");

// Access config values (We will provide accessors)
auto product_name = exp.value.get("product_name", "Awesome Product v1");
auto price = exp.value.get("price", 10.0);


// Access evaluation details such as rule id 
statsig_cpp_core::EvaluationDetails detail = exp.details;
std::cout << exp.rule_id << std::endl;  // The ID of the rule that served this config
std::cout << exp.id_type << std::endl;  // The type of the evaluation (experiment, config, etc)

// Advanced Usage:
// You can disable exposure logging for this specific check
ExperimentEvaluationOptions options;
options.disable_exposure_logging = true;
config = statsig.getExperiment(user, "an_experiment", options);


Retrieving Feature Gate Metadata

To retrieve more information about a gate evaluation than a boolean value, use the Get Feature Gate API, which returns a FeatureGate object:

cpp
FeatureGate gate = statsig.getFeatureGate(user, "example_gate");
std::cout << gate.rule_id << std::endl;
std::cout << gate.value << std::endl;

The get_feature_gate() method returns a FeatureGate object with:

  • value: The boolean gate value
  • rule_id: The ID of the rule that served this gate
  • id_type: The type of the evaluation
  • evaluation_details: Additional metadata about the evaluation

Logging an Event

After setting up a Feature Gate or Experiment, track custom events to measure how features or experiment groups affect user behavior. Call the Log Event API and specify the user and event name. You can also provide a value and metadata:

cpp
statsig.log_event(
    user,  
    "add_to_cart",
    {
        {"price", "9.99"},
        {"item_name", "diet_coke_48_pack"}
    }  
);

The log_event method supports multiple overloads:

  • log_event(user, event_name)
  • log_event(user, event_name, string_value)
  • log_event(user, event_name, string_value, metadata)

Statsig is adding support for numerical value and metadata.

Statsig User

The StatsigUser object represents a user in Statsig. You must provide a userID or at least one of the customIDs to identify the user.

When calling APIs that require a user, pass as much information as possible to enable advanced gate and config conditions (such as country or OS/browser checks) and to measure experiment impact accurately. As explained in why an ID is always required for server SDKs, at least one identifier (userID or customID) is required to provide a consistent experience for each user.

In addition to userID, the top-level fields on StatsigUser are: email, ip, userAgent, country, locale, and appVersion. You can also pass key-value pairs in the custom field to use for targeting.

Private attributes

Private attributes are user attributes used for evaluation but not forwarded to any integrations. Use them for PII or sensitive data that you don't want to send to third-party services.

cpp
  statsig_cpp_core::UserBuilder builder;
  builder.setUserID(j["userID"]);
  builder.setCustomIDs(j["customIDs"]);
  builder.setCountry(j["customIDs"]);
  statsig_cpp_core::User user = builder.build();
  // UserBuilder also supports deserialize from json

Statsig Options

You can pass an optional options parameter in addition to sdkKey during initialization to customize the Statsig client.

Available options

cpp
std::optional<std::string> specs_url;
std::optional<std::string> id_lists_url;
std::optional<std::string> log_event_url;
std::optional<std::string> output_log_level;
std::optional<std::string> environment;
bool enable_id_lists = false;
bool disable_all_logging = false;
bool disable_country_lookup = false;
bool disable_network = false;

Proxy and custom network routing

The C++ Server Core SDK currently documents endpoint overrides rather than a dedicated outbound proxy config. Use specs_url, log_event_url, and id_lists_url to route Statsig network calls through your own endpoints or proxy layer.

Example usage

cpp
statsig_cpp_core::StatsigOptionsBuilder optionsBuilder;
optionsBuilder.environment = "development";
optionsBuilder.specs_url = api_v2 + "/download_config_specs";
optionsBuilder.log_event_url = api + "/log_event";
optionsBuilder.id_lists_url = api + "/get_id_lists";
statsig_cpp_core::StatsigOptions options = optionsBuilder.build();

Shutting Statsig Down

Because events are batched and periodically flushed, some events may not have been sent when your app or server shuts down. To ensure all logged events are flushed, call shutdown() before your application exits.

cpp
statsig.shutdownBlocking();

The shutdown() method:

  • Flushes any pending events to Statsig servers
  • Cleans up resources
  • Waits for all operations to complete

Reference

API methods

  • check_gate(user: StatsigUser, gate_name: str, options: Optional[FeatureGateEvaluationOptions] = None) -> bool
  • get_dynamic_config(user: StatsigUser, config_name: str, options: Optional[DynamicConfigEvaluationOptions] = None) -> DynamicConfig
  • get_experiment(user: StatsigUser, experiment_name: str, options: Optional[ExperimentEvaluationOptions] = None) -> DynamicConfig
  • get_layer(user: StatsigUser, layer_name: str, options: Optional[LayerEvaluationOptions] = None) -> Layer
  • get_feature_gate(user: StatsigUser, gate_name: str, options: Optional[FeatureGateEvaluationOptions] = None) -> FeatureGate
  • log_event(user: StatsigUser, event_name: str, value: Optional[Union[str, float]] = None, metadata: Optional[Dict[str, str]] = None) -> None
  • shutdown() -> AsyncResult[None]

Fields needed methods

The following methods return information about which user fields are needed for evaluation.

  • get_gate_fields_needed(gate_name: str) -> List[str]
  • get_dynamic_config_fields_needed(config_name: str) -> List[str]
  • get_experiment_fields_needed(experiment_name: str) -> List[str]
  • get_layer_fields_needed(layer_name: str) -> List[str]

These methods return a list of strings representing the user fields required to evaluate the specified gate, config, experiment, or layer.

Was this helpful?