Real-Time Delivery: Short-Poll, Long-Poll, SSE, WebSocket & Webhooks
Choose by direction, latency, per-connection cost, and delivery guarantee: SSE for one-way streaming, WebSocket for true duplex, webhooks for server-to-server.
"Real-time" is a menu, not a single choice
You pick from short-poll, long-poll, SSE, WebSocket, and webhooks by four axes: latency, connection cost at your fan-out, direction of data flow, and delivery guarantee. Getting this right is mostly about not paying for a duplex, stateful connection when the workload is one-directional.
Short-polling: the client re-requests every N seconds. Dead simple and fully stateless (any server can answer any poll), so it plays nicely with load balancers. The cost is wasted requests (most polls return nothing) and up to N seconds of latency. It fits low-urgency counters, like an unread badge that can lag a few seconds.
Long-polling: the client makes a request and the server holds it open until there is data or a timeout, then the client immediately re-requests. This gets you near-real-time latency over plain HTTP that works through every proxy and firewall. The cost is that each waiting client ties up a connection and a server-side handler, and you must handle timeouts and reconnects carefully. It is the universal-compatibility fallback.
Server-Sent Events (SSE): one long-lived HTTP response over which the server streams events
(text/event-stream). It is purpose-built for one-way server-to-client streaming: notifications,
live feeds, and streaming LLM tokens. It has automatic reconnection and a Last-Event-ID for
resume built into the browser EventSource API, and because it is plain HTTP it passes through
proxies and CDNs easily. Limits: there is no client-to-server channel (the client uses normal
requests for that), and on HTTP/1.1 browsers cap concurrent connections per domain (about 6), which
HTTP/2 multiplexing relieves.
Three HTTP-based delivery mechanisms so far. Match each workload to the cheapest one that fits.
WebSocket: after an HTTP upgrade you get a full-duplex TCP connection, so both sides can push at low latency. This is the right tool for genuinely bidirectional, low-latency work: chat, presence, collaborative editing, multiplayer. The costs are real: the connection is stateful, so scaling across many server nodes needs sticky sessions or, better, a pub/sub backbone (Redis, NATS, Kafka) so a message published on node A reaches a user connected to node B. You also own heartbeats (ping/pong) and reconnect/replay logic yourself.
Webhooks: server-to-server HTTP callbacks. This is not browser delivery at all; it is how your
server notifies another server of an event (Stripe calling your endpoint on payment.succeeded).
Pair webhooks with retries, HMAC signing, and idempotency, because they will be redelivered.
one-way, low urgency ....... short-poll
one-way, near-real-time .... long-poll (fallback) / SSE (preferred)
two-way, low latency ....... WebSocket
server-to-server async ..... webhooks
Interview nuance: the classic trap is reaching for WebSocket for everything. If the data flow is one-directional (a notifications feed, LLM tokens), SSE gives you the latency without the stateful-connection and sticky-session tax. Being able to say that out loud is the signal.
Recap: choose by direction, latency, per-connection cost, and delivery guarantee: short-poll for lazy counters, long-poll as the universal fallback, SSE for one-way streaming, WebSocket for true duplex, and webhooks for server-to-server async.
Apply
Your turn
The task this lesson builds to.
Choose a real-time delivery mechanism for three features (a chat app, a notifications bell, and streaming LLM tokens back to a browser) and justify each choice against short-poll, long-poll, SSE, WebSocket, and webhooks.
Think about
- Is the data flow one-directional server-to-client, or does the client also need to push at low latency?
- What does each open connection cost at your fan-out, and how does that interact with load balancers and proxies?
- What delivery guarantee does the feature need, and who reconnects and replays missed messages?
Practice
Make it stick
A second problem on the same idea, so it survives past today.
Design the real-time delivery for a live-sports scoreboard that pushes score updates to 5 million concurrent viewers during a World Cup final, where the update is one-way (server to client), viewers join and leave in huge waves, and a few seconds of staleness is acceptable but a server meltdown is not. Choose the mechanism and explain how you fan out to 5M connections.
Think about
- Why does one-way flow at 5M connections rule out the stateful duplex option?
- How does publish-once-broadcast-many keep origin load at O(events) instead of O(viewers)?
- What absorbs the reconnect stampede after a goal?