---
title: Connection Lifecycle
description: Heartbeat, reconnection strategies, and best practices for WebSocket connections.
---

# Connection Lifecycle

## Heartbeat

Send a ping every **30 seconds** to keep the connection alive:

<CodeBlock lang="Send">
<pre>{
  <span class="s-p">"type"</span>: <span class="s-s">"ping"</span>,
  <span class="s-p">"timestamp"</span>: <span class="s-n">1769056941234</span>
}</pre>
</CodeBlock>

The server responds with:

<CodeBlock lang="Receive">
<pre>{
  <span class="s-p">"type"</span>: <span class="s-s">"pong"</span>,
  <span class="s-p">"timestamp"</span>: <span class="s-n">1769056941234</span>
}</pre>
</CodeBlock>

If the server receives no ping within 60 seconds, it closes the connection.

## Reconnection strategy

Network disruptions are inevitable. Your client should handle disconnections gracefully with exponential backoff:
1. On disconnect, wait a short initial delay (e.g., 1 second).
2. On each failed reconnection attempt, double the delay up to a maximum (e.g., 30 seconds).
3. Add random jitter to prevent thundering herd when many clients reconnect simultaneously.
4. After reconnecting, re-authenticate and re-subscribe to all channels on that connection.

<CodeBlock lang="JavaScript">
<pre><span class="s-k">const</span> <span class="s-v">BASE_DELAY</span> = <span class="s-n">1000</span>;
<span class="s-k">const</span> <span class="s-v">MAX_DELAY</span> = <span class="s-n">30000</span>;
<span class="s-k">let</span> <span class="s-v">attempt</span> = <span class="s-n">0</span>;
&#10;
<span class="s-k">function</span> <span class="s-f">reconnect</span>() {
  <span class="s-k">const</span> <span class="s-v">delay</span> = <span class="s-v">Math</span>.<span class="s-f">min</span>(<span class="s-v">BASE_DELAY</span> * <span class="s-v">Math</span>.<span class="s-f">pow</span>(<span class="s-n">2</span>, <span class="s-v">attempt</span>), <span class="s-v">MAX_DELAY</span>);
  <span class="s-k">const</span> <span class="s-v">jitter</span> = <span class="s-v">delay</span> * <span class="s-n">0.5</span> * <span class="s-v">Math</span>.<span class="s-f">random</span>();
  <span class="s-f">setTimeout</span>(() =&gt; {
    <span class="s-v">attempt</span>++;
    <span class="s-f">connect</span>(); <span class="s-c">// your connection logic</span>
  }, <span class="s-v">delay</span> + <span class="s-v">jitter</span>);
}
&#10;
<span class="s-k">function</span> <span class="s-f">onConnected</span>() {
  <span class="s-v">attempt</span> = <span class="s-n">0</span>; <span class="s-c">// reset on successful connection</span>
  <span class="s-f">authenticate</span>();
  <span class="s-f">resubscribe</span>();
}</pre>
</CodeBlock>

## Best practices

- **One connection per endpoint family** -- share one `book` connection for orderbook channels and one `nonbook` connection for everything else, rather than opening one connection per subscription.
- **Subscribe in batches** -- send all channels in a single `public/subscribe` message rather than one message per channel.
- **Handle backpressure** -- keep your message handler lightweight. Offload heavy processing (database writes, analytics) to a background queue.
- **Track subscriptions client-side** -- maintain a local registry of active subscriptions so you can re-subscribe after reconnection.
- **Use compression** -- enable `brotli` compression to reduce bandwidth, especially for high-frequency channels like `TRADE` and `BLOCK_BOOK_SNAPSHOT`.