> ## 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

> Keep 0xArchive WebSocket clients alive with ping behavior, reconnect backoff, subscription restore, and gap-aware state handling.

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

```javascript theme={"theme":"github-dark"}
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

| Concern              | Client behavior                                                            |
| -------------------- | -------------------------------------------------------------------------- |
| Liveness             | Send periodic ping messages only when the socket is open                   |
| Backoff              | Reconnect with capped exponential backoff and jitter                       |
| Subscription restore | Resubscribe after the new socket opens, using tracked active subscriptions |
| Local state          | Treat reconnect as a state transition that may require a fresh snapshot    |
| Gap events           | Mark local state unsafe until the gap is resolved or output is rebuilt     |
| Observability        | Log 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.

| Guardrail            | Behavior                                                         |
| -------------------- | ---------------------------------------------------------------- |
| Ping interval        | One active interval per socket instance                          |
| Reconnect timer      | Cancel when a new socket opens or the job stops                  |
| Retry budget         | Stop after the configured budget and surface the failure         |
| Jitter               | Add random delay so many clients do not reconnect together       |
| Subscription restore | Restore from tracked state after open, not before                |
| State rebuild        | Mark local books or alerts unsafe until a new baseline is loaded |

## Reconnect Sequence

<Steps>
  <Step title="Stop old timers">
    Clear ping intervals and pending reconnect timers attached to the closed socket.
  </Step>

  <Step title="Wait with jitter">
    Use capped backoff so network churn does not become a reconnect storm.
  </Step>

  <Step title="Open a new socket">
    Authenticate the new connection through the same safe key path.
  </Step>

  <Step title="Restore subscriptions from tracked state">
    Recreate only the active channel-symbol pairs recorded by the client.
  </Step>

  <Step title="Rebuild unsafe state">
    For local books, replay, or alert state, use a fresh snapshot or replay checkpoint before trusting output again.
  </Step>
</Steps>

## 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.

## Backpressure Link

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 connection](/websocket/connection) for the startup path and [WebSocket limits](/websocket/limits) for subscription and replay sizing.
