v3.1.0
3.1.0 (2026-09-05)
Features
Contextual Bandits
The SDK now runs contextual bandit experiments: GrowthBook trains per-segment variation weights server-side, and the SDK routes each user to their matching leaf and buckets with those weights — no client-side model. Works with encrypted payloads and the new set_payload() on both clients. Older SDKs safely serve the feature's default value.
Deferred tracking
Servers can now buffer exposures and forward them to a client SDK, which fires them in the browser via setDeferredTrackingCalls() + fireDeferredTrackingCalls() (JS SDK 1.7.0+ for the forwarded user context).
Opt in with GrowthBook(defer_tracking=True) + get_deferred_tracking_calls(), or pass a per-request TrackingBuffer to the
async client's eval methods. Buffering is independent of on_experiment_viewed, and entries are always JSON-ready.
Fixed
- Experiments that decide a prerequisite feature now fire
on_experiment_viewed— previously those exposures were silently dropped.on_feature_usagefires for every feature an evaluation touches, and the sync client's subscriptions see prerequisite experiments too. - The tracking dedupe key can no longer collide across field boundaries.
Experiment.to_dict()preserves an explicitcoverageof0.
What's Changed
- Contextual bandit support by @madhuchavva in #134
- Report prerequisite exposures and add an opt-in deferred tracking buffer by @madhuchavva in #135
See the CHANGELOG
for the full list, including behavioral details and a performance note.