intermediate
2 min answer
Multiple choice
A collaborative editor needs to push document changes to connected clients with minimal latency. Which transport should it use, and what does the choice imply for infrastructure?
Show the full answer Hide the answer
Why WebSockets
Collaborative editing is genuinely bidirectional and symmetric: every client is both a producer and a consumer of operations at similar rates. That rules out the one-directional options immediately.
- Server-Sent Events are server-to-client only. Client operations would go over separate HTTP requests, adding a round trip and connection overhead to every keystroke-level operation, and losing ordering between the two channels.
- Long polling has a round trip of overhead per message and holds a request open per client, which is the same resource cost as a persistent connection with worse latency.
- HTTP/2 server push is for pushing resources the client will request, not for application messaging, and is deprecated in practice.
What the choice implies for infrastructure
A stateful tier, with all that follows. This is the part teams underestimate.
- Connections pin to a process for their lifetime, so the connection tier cannot be load-balanced like a stateless one, and losing a process loses every session on it.
- Deployments disconnect users unless draining is a protocol feature: the server tells clients to reconnect on a staggered schedule before it goes away. Without this, every deployment is a reconnect storm — a self-inflicted version of the platform's worst failure mode.
- Layer 4 balancing rather than Layer 7, since per-request decisions are meaningless for an hours-long connection and a Layer 7 proxy becomes memory-bound holding state for it.
- Capacity is measured in connections, not requests per second. CPU is the wrong autoscaling signal — a server holding many idle connections has low CPU while approaching memory and file-descriptor limits.
- Reconnection must be cheap. A sequence number plus a bounded replay buffer, so reconnecting means "send me what I missed" rather than "refetch everything". This single property determines whether the system survives a mass disconnection.
The protocol design that matters more than the transport
- Sequence numbers on every message, so gaps are detectable and resumption is possible.
- Heartbeats in both directions, because a TCP connection can be dead for minutes without either side noticing — a half-open connection is the characteristic silent failure of long-lived connections.
- Server-enforced reconnect backoff, since client politeness is ignored by old and third-party clients.
- A message-size limit and per-connection rate limit, because a persistent connection is an unbounded input channel.
The honest caveat
If the requirement were only server-to-client notifications — a dashboard, a live feed, a progress indicator — Server-Sent Events would be the better answer: simpler, works over ordinary HTTP, reconnects and resumes automatically, and traverses proxies without special handling. WebSockets are justified by symmetry, not by "real-time", and reaching for them when the traffic is one-directional buys operational complexity for nothing.