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.
