Installation
Gradle
To install in a Gradle project, add Jitpack to your repositories, and then add the dependency with the latest version to your project’s dependencies.Maven
To install in a Maven project, add Jitpack to your repositories:Usage
There are two main approaches to using the GrowthBook Java SDK:- Enhanced Client (Recommended) - For better performance with multi-context support
- Traditional per-request approach - Create a new context and SDK instance per request
Enhanced Client (Recommended)
Available starting in version 0.9.0 For improved performance and better resource management, especially in web applications, use the enhanced client pattern. This approach allows you to reuse a single client instance across multiple requests while providing different user contexts for each evaluation while calling the feature methods likeisOn().
This GrowthBookClient instance is decoupled from the GBContext, creates a singleton featureRepository based on your refreshStrategy and uses the latest features at the time of
evaluation, all managed internally.
Basic Enhanced Client Usage
Using the Enhanced Client with Different User Contexts
Thread Safety Note
While the enhanced client is designed for concurrent use, full concurrency support is still being refined. For high-concurrency applications, consider:- Using connection pooling for database-backed sticky bucket services
- Implementing proper synchronization for custom tracking callbacks
- Testing thoroughly under expected load conditions
Traditional Usage
For new projects, we recommend using the Enhanced Client instead for better performance. There are 2 steps to initializing the traditional GrowthBook SDK:- Create a GrowthBook context
GBContextwith the features JSON and the user attributes - Create the
GrowthBookSDK class with the context
GrowthBook context
The GrowthBook contextGBContext can be created either by implementing the builder class, available at GBContext.builder(), or by using the GBContext constructor.
Using the GBContext builder
The builder is the easiest to use way to construct aGBContext, allowing you to provide as many or few arguments as you’d like. All fields mentioned above are available via the builder.
HttpClient recommendationThe above example uses
java.net.http.HttpClient which, depending on your web framework, may not be the best option, in which case it is recommended to use a networking library more suitable for your implementation.Using the GBContext constructor
You can also useGBContext constructor if you prefer, which will require you to pass all arguments explicitly.
Features
The features JSON is equivalent to thefeatures property that is returned from the SDK Connection endpoint.
- You can read more about features here
- You can see an example features JSON here
Attributes
Attributes are a JSON string. You can specify attributes about the current user and request. Here’s an example:Context#attributesJson or GrowthBook#setAttributes. This will completely overwrite the attributes object with whatever you pass in. Also, be aware that changing attributes may change the assigned feature values. This can be disorienting to users if not handled carefully.
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 a cryptographic library with SHA-256 support, and compute the SHA-256 hashed value of your attribute plus your organization’s secure attribute salt.
Using Features
Every feature has a “value” which is assigned to a user. This value can be any JSON data type. If a feature doesn’t exist, the value will benull.
There are 4 main methods for evaluating features.
isOn() / isOff()
These methods return a boolean for truthy and falsy values. Only the following values are considered to be “falsy”:nullfalse""0
isOn() will return true and isOff() will return false. If the value is “falsy”, then the opposite values will be returned.
getFeatureValue(featureKey, defaultValue)
This method has a variety of overloads to help with casting values to primitive and complex types. In short, the type of thedefaultValue argument will determine the return type of the function.
See the Java Docs for more information.
See the unit tests for example implementations including type casting for all above-mentioned methods.
evalFeature(String)
TheevalFeature method returns a FeatureResult<T> object with more info about why the feature was assigned to the user. The T type corresponds to the value type of the feature. In the above example, T is Float.
FeatureResult<T> It has the following getters.
As expected in Kotlin, you can access these getters using property accessors.
Inline Experiments
Instead of declaring all features up-front in the context and referencing them by IDs in your code, you can also just run an experiment directly. This is done with thegrowthbook.run(Experiment<T>) method.
Inline experiment return value ExperimentResult
AnExperimentResult<T> is returned where T is the generic value type for the experiment.
There’s also a number of methods available.
As expected in Kotlin, you can access these getters using property accessors.
Tracking feature usage and experiment impressions
This section covers how to track and monitor feature usage and experiment impressions in your application. There are several types of callbacks and events you can subscribe to:- Tracking Callback - Called when a user is included in an experiment
- Feature Usage Callback - Called every time a feature is evaluated
- Experiment Run Callback - Called for every experiment evaluation (regardless of inclusion)
Tracking Callback
Any time an experiment is run to determine the value of a feature, we may call this callback so you can record the assigned value in your event tracking or analytics system of choice. The tracking callback is only called when the user is in the experiment. If they are not in the experiment, this will not be called.Feature Usage Callback
Any time a feature is evaluated (regardless of experiment participation), this callback is called with the feature key and result.Experiment Run Callback
You can subscribe to experiment run evaluations using theExperimentRunCallback. This callback is called for every experiment evaluation, regardless of whether the user is included in the experiment.
Multiple Callback Subscriptions
You can subscribe to multiple experiment run callbacks:Working with Encrypted features
As of version 0.3.0, the Java SDK supports decrypting encrypted features. You can learn more about SDK Connection Endpoint Encryption. The main difference is you create aGBContext by passing an encryption key (.encryptionKey() when using the builder) and using the encrypted payload as the features JSON (.featuresJson() for the builder).
Fetching, Caching, and Refreshing features with GBFeaturesRepository
As of version 0.4.0, the Java SDK provides an optionalGBFeaturesRepository class which will manage networking for you in the following ways:
- Fetching features from the SDK endpoint when
initialize()is called - Decrypting encrypted features when provided with the client key, e.g.
.builder().encryptionKey(clientKey) - Caching features (in-memory)
- Refreshing features
RecommendationThis class should be implemented as a singleton class as it includes caching and refreshing functionality.
GBFeaturesRepository class with your own class to make it easier to work with dependency injection frameworks. Each of these instances should be singletons.
Fetching the features
You will need to create a singleton instance of theGBFeaturesRepository class either by implementing its .builder() or by using its constructor.
Then, you would call myGbFeaturesRepositoryInstance.initialize() in order to make the initial (blocking) request to fetch the features. Then, you would call myGbFeaturesRepositoryInstance.getFeaturesJson() and provided that to the GBContext initialization.
Caching and refreshing behavior
As of version 0.9.0, there are 2 refresh strategies available.Stale While Revalidate
This is the default strategy but can be explicitly stated by passingFeatureRefreshStrategy.STALE_WHILE_REVALIDATE as the refresh strategy option to the GBFeaturesRepository builder or constructor.
The GBFeaturesRepository will automatically refresh the features when the features become stale. Features are considered stale every 60 seconds. This amount is configurable with the ttlSeconds option.
When you fetch features and they are considered stale, the stale features are returned from the getFeaturesJson() method and a network call to refresh the features is enqueued asynchronously. When that request succeeds, the features are updated with the newest features, and the next call to getFeaturesJson() will return the refreshed features.
Server-Sent Events
This is a new strategy that can be enabled by passingFeatureRefreshStrategy.SERVER_SENT_EVENTS as the refresh strategy option to the GBFeaturesRepository builder or constructor.
If you’re using GrowthBook Cloud , this is ready for you to use. If you are self-hosting, you will need to set up the GrowthBook Proxy to enable it.
Overriding Feature Values
The Java SDK allows you to override feature values and experiments using the URL.Force Experiment Variations
You can force an experiment variation by passing the experiment key and variation index as query parameters in the URL you set on theGBContext. For example, if you add ?my-experiment-id=2 to the URL, users will be forced into the variation at index 2 in the variations list when evaluating the experiment with key my-experiment-id.
Force Feature Values via the URL
You can force a value for a feature by passing the key, prefixed bygb~, and the URI-encoded value in the URL’s query parameters. You must also set allowUrlOverrides to true when building your GBContext in order to enable this feature as it is not enabled by default.
dark_mode:truebanner_text:"Hello, everyone! I hope you are all doing well!"donut_price:3.33
Supported types
The value passed in the URL is cast at runtime based on the generic type argument passed in when evaluating the feature. This means that when you call
<ValueType>getFeatureValue(), what you pass into the URL must successfully cast as ValueType otherwise the value in the URL will be ignored.
All keys must be prefixed with gb~.
Using with Proguard and R8
Many Android projects use code-shrinking and obfuscation tools like Proguard and R8 in production. If you are experiencing unexpected feature evaluation results with your release Android builds that do not occur in your debug builds, it’s most likely related to this. You will need to add the following to yourproguard-rules.pro file to ensure that all of the GrowthBook SDK classes are kept so that your features are evaluated properly in projects that use Proguard and R8:

