---
title: "Reconnect with backoff and resume from the · Agent Wranglers"
url: https://agentwranglers.se/playbook/api-design/live-connections/reconnect-and-resume
updated: 2026-10-21
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Reconnect with backoff and resume from the last event

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Live connections](https://agentwranglers.se/playbook/api-design/live-connections.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers). Updated 2026-10-21.

- ID: API-72
- Level: Recommended
- Chapter: [Live connections](https://agentwranglers.se/playbook/api-design/live-connections)
- Rule: Clients wait a random time before the first reconnect and longer after each failure. They resume from the last event ID they saw, so nothing is lost or shown twice.
- How: When a server restarts, every client loses its connection at the same moment. If all reconnect at once, they knock the new server over. Delay the first try by a random time between 0 and 5 seconds. Grow later gaps as [retry with backoff and jitter](https://agentwranglers.se/playbook/api-design/reliability/retry-backoff) says. Give every event an ID in order, and keep recent events on the server. On reconnect the client sends its last ID and gets only newer events. Event streams do this with `Last-Event-ID`. When the ID is older than the kept events, send a reset event so the client reloads the full state.
- Check: Restart the server with 1,000 test clients connected. Their reconnects spread over at least 5 seconds. Each client then holds every event exactly once.

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### JavaScript example

```js
const FIRST_DELAY_MAX_MS = 5_000;
const MAX_DELAY_MS = 60_000;
let lastEventId = null;

function connect(attempt = 0) {
  const socket = new WebSocket(`wss://api.example.com/v1/live?after=${lastEventId ?? ''}`);
  socket.onopen = () => { attempt = 0; };
  socket.onmessage = message => { const event = JSON.parse(message.data); lastEventId = event.id; apply(event); };
  socket.onclose = () => {
    const ceiling = Math.min(MAX_DELAY_MS, FIRST_DELAY_MAX_MS * 2 ** attempt);
    setTimeout(() => connect(attempt + 1), Math.random() * ceiling);
  };
}
```

### Python example

```python
import asyncio, json, random
import websockets

FIRST_DELAY_MAX = 5
MAX_DELAY = 60

async def follow(last_event_id=""):
    attempt = 0
    while True:
        try:
            async with websockets.connect(f"wss://api.example.com/v1/live?after={last_event_id}") as socket:
                attempt = 0
                async for raw in socket:
                    event = json.loads(raw)
                    last_event_id = event["id"]
                    apply(event)
        except (websockets.ConnectionClosed, OSError):
            pass
        await asyncio.sleep(random.uniform(0, min(MAX_DELAY, FIRST_DELAY_MAX * 2 ** attempt)))
        attempt += 1
```

## Sources

- [RFC 6455 section 7.2.3 Recovering from abnormal closure](https://www.rfc-editor.org/rfc/rfc6455#section-7.2.3)
- [WHATWG HTML the Last-Event-ID header](https://html.spec.whatwg.org/multipage/server-sent-events.html#the-last-event-id-header)

## Related rules

- [Retry with backoff and jitter](https://agentwranglers.se/playbook/api-design/reliability/retry-backoff) in API design
- [Deliver events through a shared channel](https://agentwranglers.se/playbook/api-design/live-connections/shared-pubsub) in API design

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/api-design/live-connections/reconnect-and-resume">Agent Wranglers API design playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Send heartbeats and drop dead connections](https://agentwranglers.se/playbook/api-design/live-connections/heartbeats)
- Next: [Limit the connections and messages of each client](https://agentwranglers.se/playbook/api-design/live-connections/connection-limits)
- [Live connections](https://agentwranglers.se/playbook/api-design/live-connections)
