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

Enabling it

Call run_stream() after NexusClient::create returns. It is non-blocking and returns immediately:
The background thread handles reading the SSE stream and triggering syncs. Your application thread is never blocked by SSE activity.

What happens under the hood

  1. A background std::thread opens an HTTP 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 immediately sends a resync event, which causes the SDK to call sync() once to align with the current state.
  3. The connection stays open. Every change event triggers another full sync.
  4. While the stream is connected, the effective TTL is bumped to at least 60 s as a safety net.

Thread lifecycle

The background thread spawned by run_stream() runs until:
  • 3 consecutive transport errors exhaust the backoff - the SDK sleeps the reconnect cooldown schedule and then retries SSE automatically (it does not exit permanently)
  • The last clone of NexusClient is dropped (the thread is joined during Drop)
After STREAM_MAX_ERRORS (3) consecutive transport errors the SDK enters the reconnect cooldown schedule. During cooldown, reads continue being served from the TTL-polling cache. Once the cooldown period elapses, the thread automatically reopens the SSE connection. Your application is never notified of the transition.
There is no way to cancel the background thread from user code other than dropping all clones of NexusClient. If you need to stop SSE explicitly, drop the client (or let it go out of scope).

Reconnection and backoff

Any transport error (server restart, TCP drop, network blip) triggers a reconnect with exponential backoff: 1s - 2s - 4s - 8s - 16s - 30s (capped at 30s). After 3 consecutive transport errors the SDK falls back to TTL polling and sleeps according to the reconnect cooldown schedule before retrying SSE. The default schedule is [5, 10, 20, 40, 60] minutes (doubling up to 60 min, then staying fixed). You can override this with the sse_reconnect_cooldown config field - see Configuration for details. Unlike some other SDKs, Rust has no separate 429 code path. A 429 Too Many Requests response increments consecutive_errors the same way any other transport error does. Once the error count reaches STREAM_MAX_ERRORS, the reconnect cooldown schedule kicks in.

auth_expiring control event (WIF)

When WIF is enabled, the backend emits an auth_expiring SSE control event approximately 5 minutes before the session JWT expires. The SDK reacts by triggering a non-blocking session refresh - it does not call /sync, and the event is not surfaced to user code. When the server force-closes the stream at expiry, the background thread reconnects with the freshly-issued bearer.

What events trigger a sync

The SDK does not apply event payloads directly to the cache - every event triggers a full re-sync that returns the current authoritative state. This avoids any drift between the SDK’s view and the backend.

Disabling SSE

Just don’t call run_stream(). The SDK then runs in pure TTL-polling mode.

Clone and SSE

Because NexusClient is Clone, cloning the client after run_stream() has been called does not spawn additional SSE threads. The single background thread serves all clones - they all share the same cache.

Drop and cleanup

When the last clone of NexusClient is dropped, the Drop implementation signals the background SSE thread to stop and joins it. Any temp files written for file-type secrets are also cleaned up at this point. See Caching behaviour for details.

Connection limit by tier

Every project tier has a per-service stream connection limit: Exceeding the limit returns 429 Too Many Requests. In Rust, a 429 has no separate handling - it increments consecutive_errors like any other transport error. After 3 consecutive failures the SDK enters the reconnect cooldown schedule and retries SSE automatically once the cooldown elapses.