Requirements
- Go version 1.21 or higher (tested with 1.21, 1.22, and 1.23)
Installation
Quick Usage
Client
The client is the core component of the GrowthBook SDK. After installing and importing the SDK, create a single shared instance ofgrowthbook.Client using the growthbook.NewClient function with a list of options. You can customize the client with options such as a custom logger, client key, decryption key, default attributes, or a feature list loaded from JSON. The client is thread-safe and can be safely used from multiple goroutines.
While you can evaluate features directly using the main client instance, it’s recommended to create child client instances that include session- or query-specific data. To create a child client with local attributes, call client.WithAttributes:
WithLogger, WithUrl, and WithAttributesOverrides, can also be used to customize child clients. Since child clients share data with the main client instance, they will automatically receive feature updates.
To stop background updates, call client.Close() on the main client instance when it is no longer needed.
Additional options for sticky bucketing:
WithStickyBucketService: Provides a service implementation for storing and retrieving sticky bucket assignmentsWithStickyBucketAttributes: Sets specific attributes to use for sticky bucketing (if different from regular attributes)
Using Features
The primary method,client.EvalFeature(ctx, key), accepts a feature key and uses the stored feature definitions and attributes to evaluate the feature value. It returns a FeatureResult value that includes detailed information about why the value was assigned to the user:
Value: The JSON value of the feature (ornilif not defined), represented as aFeatureValue(an alias forinterface{}, using Go’s default behavior for JSON).OnandOff: The JSON value cast as booleans (to make your code easier to read).Source: A value of typeFeatureResultSourcethat explains why the value was assigned to the user. Possible values includeUnknownFeatureResultSource,DefaultValueResultSource,ForceResultSource, orExperimentResultSource.Experiment: Information about the experiment (if any) used to assign the value.ExperimentResult: The result of the experiment (if any) that determined the value.
Loading Features and Experiments
For the GrowthBook SDK to function, it requires feature and experiment definitions from the GrowthBook API. There are several ways to provide this data to the SDK.Automatic Features Refresh
The Go SDK provides multiple mechanisms for automatically keeping your feature definitions up to date.Server-Sent Events (SSE)
SSE provides real-time feature updates with minimal overhead. When you useWithSseDataSource(), the SDK establishes a persistent connection to receive live updates whenever features change.
- Real-time updates without polling overhead
- Lower latency for feature changes
- Reduced server load
- Automatic reconnection on connection loss
Polling Data Source
For environments where SSE isn’t supported, use polling to periodically fetch feature updates:- SSE is blocked by firewalls or proxies
- Running in restricted network environments
- Need predictable update intervals
- Simpler infrastructure requirements
Choosing Between SSE and Polling
Built-in Fetching and Caching
The loading of features is an asynchronous process so that your app is not blocked while waiting, and it can continue its initialization. If you need to ensure that the definitions are loaded, use theclient.EnsureLoaded call. This will block until the loading process finishes and will return an error if any failures occur.
EnsureLoadedis thread-safe and can be called from multiple goroutines simultaneously- Both
NewClientandEnsureLoadedrespect the contexts passed to them - The features cache is shared among all child client instances created via
client.WithXXXcalls - Use context timeouts to prevent indefinite blocking
Custom Integration
Feature definitions are stored in the client’s shared data. Normally, the data source will download them from the GrowthBook site, but you can provide an initial set during theNewClient call using the WithFeatures, WithJsonFeatures, or WithEncryptedJsonFeature options.
SetXXXFeatures client methods:
Manual Feature Updates
You can manually trigger feature updates when needed:Attributes
You can specify attributes about the current user and request. These attributes are used for the following purposes:- Feature targeting (for example, paid users receive one value, while free users receive another).
- Assigning persistent variations in A/B tests (for example, a user with id “123” always gets variation B).
Attributes type, which is an alias for Go’s generic map[string]interface{} type used for JSON objects. If you know the attributes upfront, you can pass them into NewClient using the WithAttributes option:
WithAttributes method:
WithAttributeOverrides method:
attrs, keeping the other fields from the original client instance.
Be aware that changing attributes may change the assigned feature values. This can be disorienting to users if not handled carefully. A common approach is to refresh attributes only on navigation, when the window is focused, or after a user performs a major action such as logging in.
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 Go’s crypto/sha256 package to compute the SHA-256 hashed value of your attribute plus your organization’s secure attribute salt.
Custom Attributes
You can define custom attributes for advanced targeting scenarios beyond standard user properties:- Use consistent naming conventions across your application
- Keep attribute values serializable (avoid complex nested structures)
- Consider attribute cardinality for targeting rules
- Document custom attributes in your team’s documentation
Encrypted Features
The Go SDK supports encrypted feature payloads to protect sensitive feature configurations from being exposed in transit or at rest.Setup Encrypted Features
- Enable encryption in your GrowthBook SDK Connection settings
- Copy the encryption key from the SDK Connection
- Configure the SDK with the decryption key:
Loading Encrypted Features from JSON
You can also load encrypted features directly from JSON:Security Best Practices
- Never hardcode encryption keys in source code
- Use environment variables or secret management systems (HashiCorp Vault, AWS Secrets Manager)
- Rotate keys regularly and update across all environments
- Use different keys for different environments (dev, staging, production)
Handling Decryption Errors
Sticky Bucketing
Sticky Bucketing ensures users see consistent experiment variations across sessions and devices. This is particularly useful when:- You need to slow down experiment enrollment without affecting existing users
- You want to fix bugs in an experiment without including users who saw the buggy version
- You need consistent experiences across different devices or sessions
Implementation
The SDK provides a built-in thread-safe in-memory implementation that you can use right away:BucketVersion and optionally MinBucketVersion properties:
Custom Storage Implementation
Implement your own persistent storage by implementing theStickyBucketService interface:
Key Features
-
Version Control:
BucketVersion: Controls which version of the experiment a user is assigned toMinBucketVersion: Blocks users from versions below this number
-
Attribute-Based Bucketing:
HashAttribute: Primary attribute for bucketing (usually userId)FallbackAttribute: Secondary attribute when primary is missing
-
Thread Safety:
- The in-memory implementation uses
sync.RWMutexfor concurrent access - Caching reduces database/service calls in high-traffic environments
- The in-memory implementation uses
Experiment Result Changes
TheExperimentResult returned by RunExperiment now includes a StickyBucketUsed boolean field that indicates if the variation was assigned from a sticky bucket:
Inline Experiments
Experiments can be defined and run using theExperiment type and the RunExperiment method of the client. Experiment definitions can be created directly as values of the Experiment type, or parsed from JSON using Go’s json.Unmarshal function. Passing an Experiment value to the RunExperiment method will run the experiment and return an ExperimentResult that contains the resulting feature value. This approach allows users to run arbitrary experiments without providing feature definitions upfront.
Inline Experiment Return Value
A call toRunExperiment returns a value of type *ExperimentResult:
InExperiment flag is set to true only if the user was randomly assigned a variation. If the user fails any targeting rules or is forced into a specific variation, this flag will be false.
Experiment Tracking and Feature Usage Callbacks
The Go SDK provides comprehensive tracking capabilities for monitoring experiment exposures and feature evaluations.Experiment Tracking Callback
The experiment callback is triggered when a user is included in an experiment. This is essential for analytics and experiment analysis.Tracking TimingThe experiment callback is only called when the user is actually included in the experiment. If they’re excluded from the experiment due to targeting rules or sampling, this callback won’t be triggered.
Feature Usage Callback
The feature usage callback is called every time a feature is evaluated, regardless of whether it’s part of an experiment or not.Combining Both Callbacks
You can use both callbacks together for comprehensive tracking:Using Extra Data
You can attach custom data that will be passed to each callback:Local vs Global Callbacks
Callbacks can be set globally on the main client or locally on child clients:Integration Examples
Segment.io Integration
DataDog Integration
Logging
The SDK uses theslog logger instance. You can set up your own logger using the WithLogger option when calling the NewClient function. It is also possible to create a child GrowthBook client with its own logger, parameterized with additional data, as shown below:
Further Reading
This version addresses grammatical issues and clarifies the text while maintaining the original content and code examples.

