Skip to main content
The SDK opens a long-lived connection to GET /v1/stream and refreshes the cache whenever the server says something changed, so a flag toggled in the admin console reaches the browser in milliseconds rather than at the next TTL tick. The connection is a fetch stream, and the key travels in the X-Nexus-API-Key header - never in the URL, where it would land in server access logs and browser history.

Lifecycle

Two deadlines

Connect. streamConnectTimeoutMs (15 s) bounds the attempt to open the stream. Only the attempt: an open stream has no total deadline, because it is meant to last as long as the page does. Liveness. streamIdleTimeoutMs (90 s) is the deadline that matters once the stream is open. Every received byte resets it - keepalive comments included - so a healthy but quiet stream stays open indefinitely, while a connection dropped silently by a proxy or a load balancer is detected instead of reading as healthy forever.

When it fails

Each failure schedules a reconnect on an exponential schedule with jitter: roughly 1 s, then 2 s, then 4 s. After three consecutive failures the SDK stops trying, emits the max-errors fallback, and relies on TTL polling; the stream is retried on the cooldown schedule. The jitter matters at scale. Without it, every tab of every browser holding a client reconnects on exactly the same schedule after a shared outage, turning recovery into a synchronised burst against the server that has just come back.

When it never connects at all

A stream that fails from the start is a different problem from one that drops: the values are correct on the first read and then never change, which looks like a working integration with a quiet configuration. Because the SDK has no logger by default, this used to leave no trace anywhere. The client now says so once, after it gives up on its first connection:
It goes to the logger you configured, or to console.warn if you configured none - so the message reaches the consumer least likely to be looking for it. A connection lost after one succeeded is not reported this way; that is what getStreamConnectedSignal() and the stream observer are for. The usual causes in a browser are CORS-shaped. The stream request carries X-Nexus-API-Key, which is not a CORS-safelisted header, so the browser preflights it: the endpoint has to allow this origin and name that header in Access-Control-Allow-Headers. A blocked preflight is indistinguishable from an unreachable server to the SDK, which is why the message names both.

Rate limits and quarantine

A 429 carrying Retry-After is honoured, clamped to 5-300 seconds. A 429 without one goes straight to the cooldown schedule. A quarantine response suspends both syncing and the stream until it expires, and is reported through onQuarantined - it is the server telling the client exactly how long to stay away, so it does not count as a transport failure.

Server-side rendering

The stream is never opened on the server. A long-lived connection there has no teardown hook and would hold the response open, one leaked connection per rendered request. It opens in the browser, after hydration.

Watching it

Reads keep working from the cache whatever the stream is doing, so the state is diagnostic rather than something to gate rendering on. For metrics and alerting, use the stream observer rather than scraping log output.