# Exponential backoff with jitter on client reconnection, not fixed retry interval

- **Pattern:** `ab-000738` (`community-realtime.connection-management.exponential-backoff-jitter`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000738
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000738)

## Why it matters

When a server restarts or drops a connection, every client attempts to reconnect. If all clients retry at the same fixed interval — say, 5 seconds — they form a synchronized stampede that hits the server simultaneously on each retry cycle. This thundering-herd effect can prevent the server from recovering under its own load. Jitter randomizes reconnect timing so the server receives a spread of reconnect requests it can absorb incrementally. ISO 25010 reliability includes resistance to self-inflicted load spikes of exactly this type.

## Severity rationale

High because synchronized fixed-interval retries across many clients produce a thundering-herd stampede that can prevent server recovery after an outage.

## Remediation

Implement exponential backoff with additive jitter on the client, capped at a maximum delay to prevent indefinitely long waits.

```ts
const MAX_BACKOFF = 30_000; // 30 s
let attempt = 0;

function scheduleReconnect() {
  const base   = Math.min(1_000 * 2 ** attempt, MAX_BACKOFF);
  const jitter = Math.random() * base;
  setTimeout(() => socket.connect(), base + jitter);
  attempt++;
}

socket.on('disconnect', scheduleReconnect);
socket.on('connect',    () => { attempt = 0; });
```

If you use Socket.IO's built-in reconnection, set `reconnectionDelayMax` and `randomizationFactor` rather than implementing your own loop — the default `reconnectionDelay` of 1 s without jitter is a partial fix only.

## Detection

- **ID:** `exponential-backoff-jitter`
- **Severity:** `high`
- **What to look for:** Enumerate all reconnection logic in client-side code. Count the retry mechanisms: exponential backoff calculation, jitter randomization, MAX_BACKOFF cap. Quote the actual delay formula if found.
- **Pass criteria:** The client implements exponential backoff with jitter for reconnection attempts. Delays grow with each attempt but are capped at a maximum of no more than 60 seconds. At least 1 jitter mechanism must be present.
- **Fail criteria:** The client uses a fixed retry interval (e.g., always 5 seconds), or no jitter is applied.
- **Skip (N/A) when:** Never — clients should use exponential backoff to avoid thundering herd.
- **Detail on fail:** `"Client uses fixed 5-second retry interval with no jitter. If the server goes down, all clients will reconnect simultaneously."`
- **Remediation:** Implement exponential backoff with jitter on the client:

  ```ts
  const MAX_BACKOFF = 30000; // 30 seconds
  let retryCount = 0;

  function reconnect() {
    const backoff = Math.min(1000 * Math.pow(2, retryCount), MAX_BACKOFF);
    const jitter = backoff * Math.random();
    const delay = backoff + jitter;

    setTimeout(() => {
      socket.connect();
      retryCount++;
    }, delay);
  }

  socket.on('disconnect', () => {
    reconnect();
  });

  socket.on('connect', () => {
    retryCount = 0; // Reset on successful connection
  });
  ```

## External references

- iso-25010 reliability.recoverability

Taxons: error-resilience, cost-efficiency

HTML version: https://auditbuffet.com/patterns/ab-000738
