Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.0xarchive.io/llms.txt

Use this file to discover all available pages before exploring further.

WebSocket keep-alive behavior is not only ping traffic. A correct client also needs reconnect, resubscribe, and state rebuild paths after the socket changes.

Basic Ping Loop

const keepAlive = setInterval(() => {
  if (ws.readyState === WebSocket.OPEN) {
    ws.send(JSON.stringify({ op: "ping" }));
  }
}, 25_000);
Clear the interval when the socket closes permanently or the application stops the stream. Do not let old intervals continue after reconnecting.

Keep-Alive Model

ConcernClient behavior
LivenessSend periodic ping messages only when the socket is open
BackoffReconnect with capped exponential backoff and jitter
Subscription restoreResubscribe after the new socket opens, using tracked active subscriptions
Local stateTreat reconnect as a state transition that may require a fresh snapshot
Gap eventsMark local state unsafe until the gap is resolved or output is rebuilt
ObservabilityLog close code, reason, retry count, channel set, and restored symbols

Timer And Retry Guardrails

Keep-alive bugs usually come from stale timers. Give each socket instance its own ping interval, reconnect timer, and close handler. When a socket closes permanently or is replaced, clear those handles before creating the next socket. Otherwise the client can send duplicate pings, open multiple reconnect loops, or restore subscriptions twice.
GuardrailBehavior
Ping intervalOne active interval per socket instance
Reconnect timerCancel when a new socket opens or the job stops
Retry budgetStop after the configured budget and surface the failure
JitterAdd random delay so many clients do not reconnect together
Subscription restoreRestore from tracked state after open, not before
State rebuildMark local books or alerts unsafe until a new baseline is loaded

Reconnect Sequence

1

Stop old timers

Clear ping intervals and pending reconnect timers attached to the closed socket.
2

Wait with jitter

Use capped backoff so network churn does not become a reconnect storm.
3

Open a new socket

Authenticate the new connection through the same safe key path.
4

Restore subscriptions from tracked state

Recreate only the active channel-symbol pairs recorded by the client.
5

Rebuild unsafe state

For local books, replay, or alert state, use a fresh snapshot or replay checkpoint before trusting output again.

Production Review

A client that only handles onopen and onmessage is a smoke test. A production stream consumer also handles onerror, onclose, keep-alive, replay stop conditions, gap events, unsubscribe behavior, and backpressure. Keep-alive behavior should be visible in logs so support can distinguish normal network churn from auth failure, rate pressure, or a broken consumer. Keep-alive and backpressure interact. If the message queue is growing, a healthy ping loop does not mean the stream is safe to use. Record queue depth or processing lag beside reconnect logs, and slow replay or reduce subscriptions when the consumer cannot keep up.

Next Step

Use WebSocket Connecting for the startup path and WebSocket Limits for subscription and replay sizing.
Last modified on May 18, 2026