Requirements at a glance
- An Enterprise plan — Contextual Bandits are an Enterprise-only beta feature.
- A supported SDK on a compatible version — currently JavaScript, React, Node.js, Python, Go, Kotlin (Android), and Swift (iOS) (see below).
- A connected Data Source with a warehouse the bandit can query, plus a dedicated Contextual Bandit Assignment Query that selects your user id, timestamp, and one or more context columns (see step 4).
- A Fact Metric to use as the Decision Metric — legacy (non-fact) metrics are not supported as decision metrics.
1. Install or upgrade to a compatible SDK
Contextual Bandit support ships in the following SDKs:
Install or upgrade to a compatible version with your package manager:
GBContext and GBOptions can no longer be constructed by application code — build a context through GBSDKBuilder), so read its changelog before upgrading.
What happens on older SDKs?Contextual bandit rules degrade gracefully. SDKs below the versions listed above (and all SDK languages without the capability) skip contextual bandit rules entirely and serve the feature’s default value — they never bucket users with stale or global weights. This makes it safe to roll out a contextual bandit while part of your fleet is still on older SDK versions, but users on those versions won’t enter the bandit.
2. Check your SDK Connection
Two things to verify on your SDK Connection, under SDK Configuration → SDK Connections in the GrowthBook app:- Language and version — make sure the connection’s SDK language is one of the languages listed above and its version is set to a compatible version. GrowthBook only includes contextual bandit definitions in the SDK payload for connections that support them.
- Cache TTL — contextual bandits change variation weights while running. If your SDK caches the payload longer than the bandit’s update cadence, users will be bucketed with stale weights, which slows learning and can trigger SRM warnings. Make sure your SDK’s
maxAge/ TTL settings refresh the payload significantly more often than the bandit reweights (or use streaming updates). The cache max-age recommendations for multi-armed bandits apply here too.
3. Update your tracking callback
Contextual bandits personalize variation weights based on unit attributes that are set on the GrowthBook SDK. The best way to ensure we log the attributes used to bucket units is to use the newtrackingCallback signature (with a new user argument) that allows you to pull the unit attributes that were used at evaluation time. See the JavaScript SDK docs for the full callback reference.
Furthermore, for offline debugging and for future health checks in GrowthBook, consider tracking three additional fields: leafId, banditVersion, and variationWeights. These three fields are only set for contextual bandit assignments.
user.attributes object and its fields to ensure the attributes being logged are the same as the ones being used to bucket users.
4. Create a Contextual Bandit Assignment Query
To take advantage of the above attributes and additional contextual bandit fields, you need to create a dedicated Contextual Bandit Assignment Query. This query holds the assignment SQL plus the list of context columns the bandit is allowed to split on. Manage these on your GrowthBook Datasource page under Contextual Bandit Assignment Queries, or via the createContextualBanditQuery REST endpoint. The query must select one row per exposure event with the following columns:- At least one context column (e.g.
userRole) is required — a bandit with no context to split on is just a multi-armed bandit. It should ideally match the columns you’re sending from theuserargument from your tracking callback. The set passed here must match your SDK Attributes in GrowthBook in order to be used to target the contextual bandit. leaf_id,bandit_version, andvariation_weightsare the warehouse-side counterparts of the tracking callback fields from step 3. They are optional, but you should include them — later versions of contextual bandits will use them for health checks like SRM.
5. Create the Contextual Bandit
Create the bandit under Experiments → Contextual Bandits in the left navigation. You’ll need:- A hash attribute — the attribute used to randomize users into variations, which should map to the user identifier in your assignment query. For short-lived bandits, we suggest a
session_idordevice_idthat will re-generate on future visits to ensure you get the most power while managing when a session ends yourself. - A Contextual Bandit Assignment Query — the query you created in step 4. The attribute columns you pass there will dictate the attributes that will be used to target the contextual bandit. Future versions of contextual bandits will let you select a subset of these columns to use as targeting attributes.
- Exploration window and update cadence — how long the bandit collects data before it starts reweighting, and how often it reweights after that. See the bandit configuration guide for guidance.
- A Decision Metric — the single Fact Metric the bandit optimizes toward. The same guidance as for multi-armed bandits applies: prefer a metric with a short conversion window and a conversion rate that isn’t extremely low or high.
6. Link a Feature Flag and start
Once you’ve created a contextual bandit, you can link it to a feature flag and start it. A contextual bandit serves its variations through a contextual bandit rule on a feature flag, and needs at least one linked flag before it can start:- Create (or pick) a feature flag and link it from the bandit’s page. This adds a contextual bandit rule to the flag in a draft revision.
- Define the value each bandit variation should serve.
- Start the bandit. Pending drafts on linked flags are published automatically when the bandit starts.
- Creating a feature flag via the postFeatureV2 endpoint.
- Linking the feature flag to the contextual bandit via the addContextualBanditLinkedFeature endpoint.
- Starting the contextual bandit via the startContextualBandit endpoint.
Next steps
- Driving a Contextual Bandit via API — run the same lifecycle entirely from the REST API, including refreshing and reading results.
- Contextual Bandits overview — concepts, and when to use one over a multi-armed bandit.
- Contextual Bandit technical details — how per-context weights are computed.

