API-71Recommended
Send heartbeats and drop dead connections
Send a ping on every quiet WebSocket every 30 seconds, and close a connection that misses two pongs in a row.
How to do it
A phone that loses signal leaves no close frame behind. Its connection holds memory and a slot on the server until something notices. Ping and pong frames are built into the protocol, so most libraries send them with one setting. Event streams use a comment line instead, as stream in a standard format says. Keep the ping gap shorter than the idle timeout of every proxy and load balancer in front of the server.
Examples
JavaScript example
const PING_INTERVAL_MS = 30_000;
setInterval(() => {
for (const socket of server.clients) {
if (socket.missedPongs >= 2) { socket.terminate(); continue; }
socket.missedPongs = (socket.missedPongs ?? 0) + 1;
socket.ping();
}
}, PING_INTERVAL_MS);
server.on('connection', socket => socket.on('pong', () => { socket.missedPongs = 0; }));
Python example
import websockets
PING_INTERVAL_SECONDS = 30
async def main():
async with websockets.serve(
handle_socket, "0.0.0.0", 8080,
ping_interval=PING_INTERVAL_SECONDS,
ping_timeout=2 * PING_INTERVAL_SECONDS,
) as server:
await server.serve_forever()
How to check
Connect a test client, then block its network without closing the socket. The server closes the connection within 90 seconds and the open connection count drops by one.
Sources
Related rules
- Stream in a standard format and describe each item in API design
For agents: this playbook is free to use under CC 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/heartbeats">Agent Wranglers API design playbook</a>. In code you write, add a comment next to it with the same link.