LESSON 12.1
Choosing a transport
Polling, long polling, server-sent events and WebSockets, with the latency and connection costs that decide between them.
6 min read
A chat message should appear now, not the next time someone refreshes the page. An export finishing five seconds late is usually fine. Both need updates, but they don't need the same transport. Start with how fast updates must arrive and whether data flows one way or both ways.
Polling: ask again later
The client sends an ordinary HTTP request every few seconds, usually with a cursor or version so the server returns only changes. It's easy to build, works through normal HTTP infrastructure, and doesn't require keeping a request open between checks.
The cost is repeated work even when nothing changes. With updates arriving uniformly between polls, a 5-second interval adds about 2.5 seconds of average waiting, plus network and processing time. Conditional requests can save response bytes, but still reach a server or cache.
- Poll every 30 secondsAbout 15 s average waiting
- About 3,333 requests / s
- Poll every 5 secondsAbout 2.5 s average waiting
- 20,000 requests / s
- Poll every secondAbout 0.5 s average waiting
- 100,000 requests / s
Add jitter so clients don't all poll on the same second. Back off when a tab is hidden or a job has finished.
Long polling: leave a request waiting
The server holds the request until there's an update or a timeout, say 25 seconds. It responds, and the client immediately asks again with its latest cursor. Updates normally arrive without waiting for a fixed interval.
Idle clients still renew timed-out requests: 100,000 clients with 25-second holds generate about 4,000 renewals a second. Frequent updates cause frequent response-and-reconnect cycles. The server needs asynchronous request handling so waiting clients don't each consume a blocked thread.
SSE and WebSockets: keep the stream open
Server-sent events (SSE) keep an HTTP response open with text/event-stream. The server writes text events as changes arrive. The browser's EventSource reconnects automatically; event ids let the application resume, covered in the delivery lesson. It's one-way delivery, so the client sends commands through separate HTTP requests. MDN's SSE guide describes the event format and reconnect behavior.
WebSockets establish a persistent, bidirectional connection. Either side can send text or binary messages without a new HTTP request. They're useful for chat, games and frequent interactive commands, but the application must handle reconnects, heartbeats and resuming missed messages.
Polling
- Simple HTTP requests
- Easy to cache and operate
- Empty requests
- Latency depends on the interval
Pick it when: Occasional changes where seconds of delay are fine.
Long polling
- Updates arrive promptly
- Works with request-response APIs
- Repeated requests on timeout or delivery
- Holds server and proxy resources
Pick it when: A compatibility fallback or modest update volume.
SSE
- One continuous HTTP response
- Browser reconnect support
- Server to client only
- Text events
Pick it when: Dashboards, notifications and progress updates.
The transport isn't the whole design
Both streaming options hold connection state. Configure proxy idle timeouts, disable buffering for SSE, and send heartbeats during quiet periods. A stream buffered by a proxy isn't real-time, however quickly the application writes events.
Try it
Chat Service HLD
Choose a transport for messages, typing indicators and read receipts.