Choosing a Real-Time Transport
You'll learn to
- -Compare polling, long polling, Server-Sent Events and WebSockets by direction, overhead and reconnection
- -Design resume so a client that drops and reconnects misses no events
- -Use heartbeats to detect dead connections, and backoff with jitter to avoid a reconnect stampede
- -Pick the simplest transport that fits a given product
Plain HTTP is a question and an answer: the client asks, the server replies, and the conversation ends. A live scoreboard, a chat window or a presence dot needs the opposite, where the server speaks first. There are four common ways to get there, and they differ in direction, cost and how well they survive a bad network.
An Analogy: Four Ways to Get the News
Polling is walking to the mailbox every minute to check. Long polling is asking the clerk for news and having them stand there until something arrives, then asking again. Server-Sent Events is tuning in to a one-way radio broadcast. A WebSocket is a phone call, where either side can talk at any time. Each is right for a different job.
The Four Options
- -Polling: the client repeats GET /scores every few seconds. Simple and cache-friendly, but most answers are 'nothing new' and updates arrive late by up to one interval.
- -Long polling: the server holds the request open until there is something to send or a timeout of about 30 seconds passes. Updates are prompt and it works everywhere, but every event costs a new request.
- -Server-Sent Events (SSE): one long-lived HTTP response that streams events one way, server to client. Browsers reconnect on their own and send the last event id they saw.
- -WebSocket: an HTTP request upgraded into a two-way connection (RFC 6455). Lowest overhead per message, and the right tool when the client talks as much as the server.
Direction is the first question. If only the server pushes, SSE is usually enough and plays well with proxies, caches and ordinary HTTP authentication. If both sides send frequent messages, as in chat or collaborative editing, use a WebSocket. Long polling is the fallback for networks that block everything else, and polling is fine when updates are rare.
The three pictures below show the same scoreboard growing up. First the client keeps asking, then the server pushes, then a fleet of push servers shares one stream of events, so a viewer can be connected to any of them.
Most answers are 'nothing new', and an update can wait up to one interval.
One long-lived connection. Each event carries an increasing id.
Any push server can serve any viewer, because the events come from a shared bus.
Resuming After a Drop
Mobile networks drop connections constantly, so a real-time API must assume the client will miss events. The fix is to give every event an increasing id. The client remembers the last id it processed and sends it when it reconnects: SSE does this automatically with the Last-Event-ID header, and a WebSocket client sends it in its first message. The server keeps a short replay buffer and sends only what was missed.
The buffer cannot be infinite. If the client has been away longer than the buffer reaches, the server cannot fill the gap, and it should say so, for example with a resync message, so the client refetches the full state from a normal endpoint and then continues from the stream. The block below shows both cases, followed by a reconnect schedule that uses backoff with jitter. Press Run and read the delays.
The first line shows the replay: events 4, 5 and 6 come back and nothing is repeated. The second shows the resync answer. In the schedule, each wait is a random value between zero and the cap, and the cap doubles up to 30 seconds. Because every client picks a different random wait, a server that restarts and drops 100,000 connections does not see 100,000 reconnects in the same instant.
Try it yourself in the demo below. Change how long the client was away and how many events the server keeps, and watch the answer switch between a replay and a resync at exactly the point where the gap outgrows the buffer.
Reconnect: Replay or Resync?
A phone loses signal and comes back. Every event had an increasing id, and the server keeps a short replay buffer. Move the sliders to see when a replay is enough and when the client has to start over from the full state.
Events missed
40
2 per second for 20 seconds
Server answers
Replay 40
from Last-Event-ID
Longest outage covered
50 s
buffer size divided by event rate
Reconnect waits (random, up to): 2 s, 4 s, 8 s, 16 s, 30 s, 30 s. Each client picks its own random value, so a restart does not bring every client back at once.
The client sends the id of the last event it saw. The server finds 40 newer events in its buffer and replays exactly those, in order, so the screen is right again with no reload.
Heartbeats and Dead Connections
A connection can die without either side noticing: a phone enters a tunnel, a NAT table forgets the mapping, a proxy closes an idle stream. TCP may not report it for minutes. So the server sends a small heartbeat every 15 to 30 seconds (an SSE comment line, or a WebSocket ping), and the client treats two missed heartbeats as a dead connection and reconnects. The same heartbeat also stops idle-timeout rules in proxies from closing a quiet stream.
Running It at Scale
- -Each open connection holds a socket and memory, so one server may carry tens of thousands, and you size for connections as well as requests.
- -Keep no per-user state that only one server knows. Publish events through a shared bus so any server can push to any connected client.
- -Authenticate when the connection opens, and plan for the token to expire while the connection is still up: re-authenticate or close with a clear code.
- -Protect the server from slow clients with a bounded send buffer. When it fills, drop the oldest events or disconnect the client, and let resume repair the gap.
- -Over HTTP/1.1, browsers allow only about six connections per domain, which a few open event streams can use up. Serve streams over HTTP/2, where many of them share one connection.
Pick the simplest transport that does the job: SSE for one-way pushes such as scores, notifications and progress, a WebSocket for two-way traffic such as chat and shared editing, and long polling only where the network forces it. Whichever you choose, event ids, resume, heartbeats and jittered reconnect are what make it dependable.
Interview Signal is part of Pro
See a real weak answer next to a real strong one for this exact topic.
Quiz is part of Pro
Test what you just read with a short quiz, and bank the XP.
Scoreboard Live, Long-Poll Lifeline and Socket Sync in the API Design Lab.
Discussion0
Join the Discussion
Sign in to leave comments, reply to others, or like insights.
No comments yet. Be the first to start the thread!