Skip to content

Streaming and Caching

By default, gb.init() performs a one-shot HTTP fetch to retrieve the latest feature definitions from the GrowthBook CDN. This is fine for many use cases, but it means flag changes only take effect the next time init() runs — typically on a page load or server restart. Two mechanisms change that story: SSE streaming and the feature cache.

GrowthBook supports Server-Sent Events (SSE) to push definition updates in real time. Pass streaming: true to init(), or call gb.startStreaming() after initialization. When flag values change in the GrowthBook UI, the SDK receives the update within seconds — no redeploy needed.

This is especially useful for long-lived processes (Node servers, SPAs staying open for hours) where you want flag changes to take effect immediately without a restart.

The SDK maintains an in-memory cache keyed by clientKey. The cache respects a staleTTL value (default 60 000 ms / 60 seconds). After the TTL expires, the next init() call triggers a re-fetch. You can lower or raise the TTL globally:

configure({ staleTTL: 30000 }); // 30 seconds

When streaming is enabled, the cache is kept up to date by incoming SSE events, so the TTL matters less — it acts as a fallback for reconnection scenarios.

await gb.refreshFeatures() forces an immediate re-fetch regardless of whether the cache is still fresh. Use it after a user action that might correlate with a flag change (for example, after a user upgrades their plan) or when reconnecting after a network outage.

gb.setPayload(payload) directly injects a feature definitions object into the SDK without making any network request. This is the recommended pattern for SSR: fetch the definitions on the server (where you can cache them however you like), serialize them into the page, and call setPayload on the client. The client SDK then starts with correct flag values instantly — no extra round-trip.

import { GrowthBook, configure } from '@growthbook/growthbook';

// Configure global cache TTL (30 seconds)
configure({ staleTTL: 30000 });

const gb = new GrowthBook({
  apiHost: 'https://cdn.growthbook.io',
  clientKey: 'sdk-abc123',
});

// Init with streaming enabled — flags update in real time
await gb.init({
  timeout: 3000,
  streaming: true,
});

// The SDK now listens for SSE updates automatically.
// Flags will refresh within seconds when changed in the UI.

// Manual refresh (useful after a user event or on reconnect)
await gb.refreshFeatures();

// Inject a payload fetched server-side (avoids a client-side request)
const ssrPayload = { features: { 'dark-mode': { defaultValue: true } } };
gb.setPayload(ssrPayload);

console.log(gb.isOn('dark-mode')); // true
How do you enable real-time SSE flag updates in the GrowthBook SDK?
What does `staleTTL` control?
Which method forces an immediate re-fetch of feature definitions, ignoring cache?
What is the main use case for `gb.setPayload()`?