Installation
Quick Usage
Async Client (Recommended)
Available starting in version 1.2.0 For improved performance and better resource utilization, especially in async web applications, use theGrowthBookClient class. This approach provides up to 3x better performance by reusing a single client instance across multiple requests instead of creating new instances per request.
Basic Async Usage
Real-time Feature Updates
The async client supports real-time feature updates using Server-Sent Events:Concurrency and Thread Safety
The async client is designed to be thread-safe and handle concurrent requests efficiently. You can safely use a single client instance across multiple coroutines:UserContext instance across different requests. Create a new UserContext for each request to maintain proper isolation.
Performance Benefits
TheGrowthBookClient provides significant performance improvements over the traditional per-request GrowthBook approach:
- 3x faster feature evaluations due to instance reuse
- Lower memory usage by sharing feature data across requests
- Built-in caching with configurable refresh strategies
- Real-time updates without polling overhead
- Async/await support for non-blocking operations
Loading Features
There are two ways to load feature flags into the GrowthBook SDK. You can either use the built-in fetching/caching logic or implement your own custom solution.Built-in Fetching and Caching
Both the async client and traditional client support built-in fetching and caching of feature flags.- Async Client
- Legacy Client
For the async client, use
GrowthBookClient with Options:Custom Caching
GrowthBook comes with a custom in-memory cache.- Legacy Client
For the traditional client, configure a custom cache globally:
Custom Implementation
If you prefer to handle the entire fetching/caching logic yourself, you can just pass in adict of features from the GrowthBook API directly into the constructor:
api_host or client_key and you don’t need to call gb.load_features().
GrowthBook class
The GrowthBook constructor has the following parameters:- enabled (
bool) - Flag to globally disable all experiments. Default true. - attributes (
dict) - Dictionary of user attributes that are used for targeting and to assign variations - url (
str) - The URL of the current request (if applicable) - qa_mode (
boolean) - If true, random assignment is disabled and only explicitly forced variations are used. - on_experiment_viewed (
callable) - A function that takesexperimentandresultas arguments. - api_host (
str) - The GrowthBook API host to fetch feature flags from. Defaults tohttps://cdn.growthbook.io - client_key (
str) - The client key that will be passed to the API Host to fetch feature flags - decryption_key (
str) - If the GrowthBook API endpoint has encryption enabled, specify the decryption key here - cache_ttl (
int) - How long to cache features in-memory from the GrowthBook API (seconds, default60) - features (
dict) - Feature definitions from the GrowthBook API (only required ifclient_keyis not specified) - forced_variations (
dict) - Dictionary of forced experiment variations (used for QA)
Attributes
You can specify attributes about the current user and request. These are used for two things:- Feature targeting (e.g. paid users get one value, free users get another)
- Assigning persistent variations in A/B tests (e.g. user id “123” always gets variation B)
- Async Client
- Legacy Client
For the async client, attributes are passed via
UserContext for each evaluation:Secure Attributes
When secure attribute hashing is enabled, all targeting conditions in the SDK payload referencing attributes with datatypesecureString or secureString[] will be anonymized via SHA-256 hashing. This allows you to safely target users based on sensitive attributes. You must enable this feature in your SDK Connection for it to take effect.
If your SDK Connection has secure attribute hashing enabled, you will need to manually hash any secureString or secureString[] attributes that you pass into the GrowthBook SDK.
To hash an attribute, use the hashlib library with SHA-256 support, and compute the SHA-256 hashed value of your attribute plus your organization’s secure attribute salt.
- Async Client
- Legacy Client
For the async client, hash secure attributes before creating the
UserContext:Tracking Experiments
Any time an experiment is run to determine the value of a feature, you want to track that event in your analytics system.- Async Client
- Legacy Client
For the async client, you can set up experiment tracking through the You can also use synchronous callbacks with the async client:
Options:Tracking Plugins
Available starting in version 1.3.0 The Python SDK supports tracking plugins that provide automated event tracking with batching, error handling, and retry logic. This is the recommended approach for production applications as it handles edge cases and provides better reliability than custom tracking callbacks.Built-in Tracking Plugin
The SDK includes a built-in tracking plugin that automatically batches and sends events:- Async Client
- Legacy Client
Multiple Tracking Plugins
You can use multiple tracking plugins to send events to different analytics systems:Tracking Plugin Benefits
The tracking plugin system provides several advantages over custom tracking callbacks:- Automatic Batching: Events are batched together to reduce API calls
- Error Handling: Failed requests are automatically retried with exponential backoff
- Non-blocking: Tracking doesn’t block feature evaluations
- Configurable: Batch sizes, intervals, and retry logic can be customized
- Multiple Destinations: Send events to multiple analytics systems simultaneously
Working with Traditional Callbacks
Tracking plugins work alongside your existingon_experiment_viewed callbacks:
Using Features
There are 3 main methods for interacting with features.gb.is_on("feature-key")returns true if the feature is ongb.is_off("feature-key")returns false if the feature is ongb.get_feature_value("feature-key", "default")returns the value of the feature with a fallback
gb.evalFeature("feature-key") to get back a FeatureResult object with the following properties:
- value - The JSON-decoded value of the feature (or
Noneif not defined) - on and off - The JSON-decoded value cast to booleans
- source - Why the value was assigned to the user. One of
unknownFeature,defaultValue,force, orexperiment - experiment - Information about the experiment (if any) which was used to assign the value to the user
- experimentResult - The result of the experiment (if any) which was used to assign the value to the user
Sticky Bucketing
Available starting in version 1.1.0 By default GrowthBook does not persist assigned experiment variations for a user. We rely on deterministic hashing to ensure that the same user attributes always map to the same experiment variation. However, there are cases where this isn’t good enough. For example, if you change targeting conditions in the middle of an experiment, users may stop being shown a variation even if they were previously bucketed into it. Sticky Bucketing is a solution to these issues. You can provide a Sticky Bucket Service to the GrowthBook instance to persist previously seen variations and ensure that the user experience remains consistent for your users. A sampleInMemoryStickyBucketService implementation is provided for reference, but in production you will definitely want to implement your own version using a database, cookies, or similar for persistence.
Sticky Bucket documents contain three fields
attributeName- The name of the attribute used to identify the user (e.g.id,cookie_id, etc.)attributeValue- The value of the attribute (e.g.123)assignments- A dictionary of persisted experiment assignments. For example:{"exp1__0":"control"}
- Async Client
- Legacy Client
Note: The Async Client currently uses the synchronous sticky bucket interface. This means sticky bucket operations running in the main event loop may block. We recommend using a fast, local store (like the default in-memory one) or an optimized synchronous store.
Inline Experiments
Instead of declaring all features up-front and referencing them by ids in your code, you can also just run an experiment directly. This is done with therun method:
- Async Client
- Legacy Client
For the async client, use
await with the run method:- key (
str) - The globally unique tracking key for the experiment - variations (
any[]) - The different variations to choose between - seed (
str) - Added to the user id when hashing to determine a variation. Defaults to the experimentkey - weights (
float[]) - How to weight traffic between variations. Must add to 1. - coverage (
float) - What percent of users should be included in the experiment (between 0 and 1, inclusive) - condition (
dict) - Targeting conditions - force (
int) - All users included in the experiment will be forced into the specified variation index - hashAttribute (
string) - What user attribute should be used to assign variations (defaults to “id”) - hashVersion (
int) - What version of our hashing algorithm to use. We recommend using the latest version2. - namespace (
tuple[str,float,float]) - Used to run mutually exclusive experiments.
Inline Experiment Return Value
A call torun returns a Result object with a few useful properties:
inExperiment flag will be false if the user was excluded from being part of the experiment for any reason (e.g. failed targeting conditions).
The hashUsed flag will only be true if the user was randomly assigned a variation. If the user was forced into a specific variation instead, this flag will be false.
Example Experiments
- Async Client
- Legacy Client
3-way experiment with uneven variation weights:
- Async Client
- Legacy Client
- Async Client
- Legacy Client
- Async Client
- Legacy Client
Working with Encrypted Features
The Python SDK supports encrypted feature flags for enhanced security. When encryption is enabled, the feature payload is encrypted before being sent from GrowthBook, and the SDK automatically decrypts it client-side.- Async Client
- Legacy Client
For the async client, provide the decryption key in the
Options:Environment Variables
You can also set the decryption key via environment variable:- Async Client
- Legacy Client
Error Handling
If decryption fails (wrong key, corrupted data, etc.), the SDK will log an error and treat all features as disabled/default values:Logging
The GrowthBook SDK uses a Python logger with the namegrowthbook and includes helpful info for debugging as well as warnings/errors if something is misconfigured.
Here’s an example of logging to the console
Integration Examples
This section provides practical examples for integrating GrowthBook with popular web frameworks.Async Web Framework Integration (FastAPI)
The async client works great with modern async web frameworks like FastAPI:Starlette Integration
Traditional Web Frameworks (Django, Flask, etc.)
For new projects, we recommend using the Async Client instead for better performance. For traditional synchronous web frameworks, you should create a newGrowthBook instance for every incoming request and call destroy() at the end of the request to clean up resources.

