Back to docsRecipe

WebSocket server design + heartbeats

A production-ready WebSocket server architecture with bidirectional heartbeats, exponential backoff reconnection, and graceful shutdown semantics.

Core loop

for {
  select {
  case <-ctx.Done():
    return
  case msg := <-inbound:
    dispatch(msg)
  case <-ticker.C:
    writePing()
  case <-pongDeadline.C:
    reconnect()
  }
}

Heartbeat contract

  • Ping interval: 15s, sent by server when idle.
  • Pong deadline: 10s after ping; missed pong triggers reconnect.
  • Client-initiated: client may ping; server must pong within 5s.

Reconnection strategy

AttemptDelayJitter
11s±200ms
22s±400ms
34s±800ms
4+30s cap±2s

Graceful shutdown

On SIGTERM, drain the write buffer (5s deadline), send a close frame with code 1001, then terminate the TCP connection. In-flight messages are acknowledged before the socket is released.