How to implement automatic WebSocket reconnection
exponential backoff, jitter, max retry limit, reconnect on close code, storing pending messages, reconnect state flag, clearTimeout cleanup
WebSockets Drop - Your Client Must Recover
Network drops, server restarts, and idle timeouts all close WebSocket connections. A production client must reconnect automatically. Naive immediate reconnect hammers the server. Use exponential backoff:
let retryCount = 0;
let retryTimeout = null;
function connect() {
const ws = new WebSocket('wss://api.example.com/ws');
ws.onopen = () => {
retryCount = 0; // reset on success
};
ws.onclose = (event) => {
if (event.code === 1000) return; // intentional close
const delay = Math.min(1000 * 2 ** retryCount, 30000);
const jitter = Math.random() * 1000;
retryCount++;
retryTimeout = setTimeout(connect, delay + jitter);
};
return ws;
}Jitter Is Not Optional
Without jitter, every client that lost connection at the same moment (server restart) reconnects at exactly the same intervals, creating synchronized thundering herds. Adding Math.random() * 1000 spreads reconnect attempts across a one-second window, which reduces load spikes dramatically at scale.
Cap retry delay at 30 seconds. After 5–10 failures, surface a UI message so users know they are offline rather than leaving them staring at a spinner indefinitely. Always cancel pending setTimeout calls when the component unmounts or the user navigates away.
