Skip to main content
The SDK can hold a persistent GET /v1/stream connection on a tokio task. When the backend emits a change event (config.updated, flag.toggled, secret.created, resync, …) the SDK triggers an immediate full sync, so the cache updates within milliseconds instead of waiting for the next TTL tick.

Enabling it

It is idempotent: a second run_stream() does not open a second connection, and returns a handle whose is_owner() is false.

What happens under the hood

  1. A tokio task opens a streaming response to <endpoint>/v1/stream with Accept: text/event-stream and either X-Nexus-API-Key: <key> or Authorization: Bearer <session_jwt> (when WIF is enabled).
  2. The server sends a resync event immediately; the SDK syncs once to align.
  3. The connection stays open, and every change event triggers another full sync.
  4. Bytes are buffered and split into lines before being decoded, so a multi-byte character split across a TCP chunk boundary is reassembled rather than mangled.

Deadlines

There is deliberately no total deadline - the connection is long-lived by design. The idle deadline resets on every byte received, keepalive comments included, which is what makes a connection silently dropped by a load balancer detectable rather than healthy-looking forever.

Task lifecycle

The task runs until:
  • StreamHandle::abort() is called - the client continues in TTL-polling mode,
  • close() is called,
  • or the last clone of NexusClient is dropped. The task holds only a weak reference, so it never keeps a dropped client alive.
Dropping the StreamHandle leaves the stream running.

Reconnection and backoff

Any transport error triggers a reconnect with exponential backoff: 1 s, 2 s, 4 s, 8 s, 16 s, capped at 30 s. After 3 consecutive transport errors the SDK falls back to TTL polling and waits according to the reconnect cooldown schedule before retrying SSE. The default is [5, 10, 20, 40, 60] minutes (doubling, then staying at 60); override it with sse_reconnect_cooldown in Configuration. Your application is not notified of the transition - the tracing output records it.

429 handling

A 429 carrying a quarantine body is not a transport error: the SDK records the quarantine, waits it out (capped at 10 minutes per attempt; the quarantine itself is clamped to 24 hours) and does not count the pause towards the error budget. The sync path is paused by the same state. Any other 429 - for example exceeding the tier’s stream connection limit - is a RateLimited transport error and counts towards the backoff.

auth_expiring control event (WIF)

With WIF enabled, the backend emits auth_expiring about five minutes before the session JWT expires. The SDK reacts by forcing a session refresh - the local pre-emptive window is one minute, so without forcing, an event five minutes ahead would do nothing. It does not call /v1/sync, and the event is not surfaced to your code. When the server closes the stream at expiry, the task reconnects with the fresh bearer.

What events trigger a sync

The SDK never applies an event payload to the cache directly - every event triggers a full re-sync that returns the current authoritative state, which avoids drift.

Disabling SSE

Do not call run_stream(); the SDK then runs in pure TTL-polling mode.

Clone and SSE

Cloning the client after run_stream() spawns no further tasks: one task serves every clone, and they share one cache.

Connection limit by tier