Real-Time APIs · Scaling Real-Time Systems
Slow Clients and Backpressure
Protect servers from consumers that can't keep up.
A client on a slow network can't drain messages fast enough, so the server's send buffer grows. Without limits, a few slow clients exhaust memory. Monitor per-connection buffered bytes (bufferedAmount/socket write buffer), apply policies: drop non-critical updates (send only the latest state — conflation), disconnect clients exceeding limits (they reconnect and resync), and keep messages small. For high-frequency data (prices, positions), conflate to the latest value per key.
Slow consumer policies
| Policy | Use for | Effect |
|---|---|---|
| Unbounded buffering | Never | Memory exhaustion |
| Drop non-critical | Typing, cursor positions | Client sees fewer updates |
| Conflate (latest per key) | Prices, positions, counters | Always current, fewer messages |
| Disconnect + resync | Critical streams | Client reloads state |
TypeScript (ws)
const MAX_BUFFER = 1 * 1024 * 1024; // 1 MB
function sendOrDrop(ws: WebSocket, msg: Message) {
if (ws.bufferedAmount > MAX_BUFFER) {
if (msg.critical) return ws.close(4008, "slow consumer"); // client will reconnect and resync
return metrics.increment("ws.dropped"); // drop non-critical update
}
ws.send(JSON.stringify(msg));
}
// Conflation: keep only the latest price per symbol and flush every 100 ms
const latest = new Map<string, Price>();
setInterval(() => { for (const [, p] of latest) broadcast(p); latest.clear(); }, 100);
Common pitfalls
- Ignoring bufferedAmount.
- Sending every intermediate value of fast-changing data.
- Large JSON messages for frequent updates.
Key points
- Bound per-connection buffers
- Conflate high-frequency data
- Disconnect and resync when needed
Further reading: MDN: WebSocket.bufferedAmount
Practice questions
What is conflation in real-time systems?
Answer
Replacing queued updates for the same key with the latest value, so slow clients receive the current state instead of every intermediate change.
Why disconnect a slow client instead of buffering?
Answer
Unbounded buffering threatens the server's memory and other clients; disconnecting forces a clean reconnect and state resync.
Open in the app to mark lessons complete, take notes and track your progress.