Choosing a real-time transport
"Real-time" is four different mechanisms with very different bills. Here are all four delivering the same eight updates over the same sixty seconds:
Polling's problem is arithmetic, not engineering
Ask every five seconds and an update that arrives just after a poll waits nearly five seconds. On average it waits half the interval — and no amount of network speed changes that, because the delay is in the schedule rather than in the wire.
Halving the interval halves the delay and doubles the request count. There is no setting that gives you both, which is the whole reason the other three exist.
| Transport | Requests / min | Latency | Direction |
|---|---|---|---|
| Polling | 60/interval | Half the interval | Both, awkwardly |
| Long polling | ~1 per event | Near zero | Both, awkwardly |
| SSE | 1 | Near zero | Server → client |
| WebSocket | 1 | Near zero | Both, natively |
Picking one
Long polling removes the delay by holding a request open until there is something to say — at the cost of one held-open request per connected client, which is real server-side capacity.
SSE is one ordinary HTTP response that never ends, with events at roughly eight bytes
each. It gives up sending anything back, and in exchange gets automatic reconnection and
event replay via Last-Event-ID for free.
A WebSocket pays a few hundred bytes once and then costs two to fourteen bytes of header per message, in both directions. It is the right answer when the client genuinely needs to send — a chat, a collaborative editor, a game — and overkill when it does not.
Key takeaways
- Polling’s average delay is half the interval, and no network improvement changes it.
- Halving the poll interval halves the delay and doubles the request count — there is no setting that gives both.
- Long polling removes the delay but holds one open request per connected client.
- SSE is one HTTP response with events on it, and gets reconnection and Last-Event-ID replay for free.
- A WebSocket earns its complexity when the client genuinely needs to send; for one-directional traffic it means rebuilding what SSE already does.