Concept lesson · Foundations
Real-time communication: polling, long polling, SSE, and WebSocket
Start here
Definition
Real-time application communication delivers updates with a product-defined small delay. Polling repeatedly asks for changes; long polling holds a request until data or timeout; SSE streams server-to-client events over HTTP; WebSocket supports messages in both directions over a persistent channel.
Why it matters: A chat, dashboard, or live notification screen must learn about server changes without a manual page refresh. The transport choice changes latency, idle traffic, connection state, and recovery work.
Illustrative timing omits network and processing delay. The transports differ in request direction and connection lifetime; reconnect still needs a durable event cursor.
Read the diagram step by step
- With polls at time 0 and 5, an event at time 2 waits three seconds for the next poll.
- Long polling holds a request until an event or timeout. SSE streams server-to-client events. WebSocket sends message 501 at time 2 seconds and allows a client reply at 2.1 seconds on the same persistent channel. Network and processing delays are omitted from this illustrative timeline.
- None of these transports alone makes delivery durable or exactly once. Resume after message 500 and deduplicate event 501.
Worked example
Message 501 arrives at 17:00:02. A client polling every five seconds might receive it at 17:00:05. A waiting long poll, open SSE stream, or WebSocket can deliver it immediately after processing and network delay.
Key takeaways
- Choose by direction, frequency, and acceptable delay, not by the word real-time.
- An open connection does not provide durable history or exactly-once delivery.
- Reconnect with a cursor and deduplicate messages; define how expired history is recovered.
You will learn to
- Describe the request lifecycle and direction of all four update techniques.
- Compare latency and request overhead using the receiving client’s message timeline.
- Design authenticated resumption and bounded buffers after a connection fails.
Practice in this chapter
8 interview questions with model answers and follow-ups.
Go to interview practiceUseful foundations: HTTP APIs and request lifecycle · Replication and durability
Workload and timing examples are interview assumptions.
Dotted concept links open the relevant explanation in a new tab.
01What does real-time communication mean?
Real-time communication in these interviews means delivering updates quickly enough for the product, such as chat messages appearing within a fraction of a second. It is not a hard real-time guarantee that every deadline is mathematically bounded. First name the acceptable delay and whether traffic is one-way or two-way.
The four common choices are short polling (repeat requests), long polling (hold one request until an update), server-sent events or SSE (keep a server-to-client HTTP event stream open), and WebSocket (exchange messages in both directions on one persistent channel). All still need authentication, reconnection, and a policy for missed updates.
A live update needs both a way to transmit messages and rules for storing, acknowledging, and recovering them. In this example, a receiving client has processed every message through ID 500 and saved that progress. We call 500 its last-applied cursor, the position from which it can safely resume. The server durably stores message 501 at 17:00:02. Compare how polling, long polling, SSE, and WebSocket deliver that new event; then handle reconnection independently of the transport.
An ordinary HTTP exchange begins when a client asks for something and ends when the server returns a response. The receiving client can request messages after 500, and the server can return an empty list if none exist yet. A later server event does not automatically produce another ordinary response after that exchange has finished.
HTTP requests can reuse an existing network connection; a new request does not always mean a new TCP or TLS setup. The central distinction in this lesson is the lifecycle of requests and application messages. Our timestamps, five-second polling interval, and client counts are explicit example assumptions, not measurements of a real messenger.
02Short polling: periodic requests and delay
With periodic Ajax polling, browser code repeats an HTTP request at a fixed interval. “Ajax” here means the page requests data asynchronously while remaining displayed; XML is not required. The receiving client asks at 17:00:00 and receives no new messages. Message 501 appears at 17:00:02, but its next scheduled request is at 17:00:05. The receiving client waits approximately three seconds plus network and processing time.
| Time | Client action | Result |
|---|---|---|
| 17:00:00 | GET messages after 500 | Empty response |
| 17:00:02 | No request scheduled | 501 waits on server |
| 17:00:05 | GET messages after 500 | Receive 501 |
Polling is simple and fits modest update frequency or relaxed freshness requirements. At 100,000 clients polling every five seconds, even an idle service receives about 20,000 requests/second. Randomly arriving events wait about half an interval on average under a uniform-arrival assumption. Poll less often to reduce work, but accept more delay.
03Long polling: one held request per response
Long polling changes the empty-response behavior. The receiving client requests messages after 500 at 17:00:00. Instead of immediately returning an empty list, the server holds the request. At 17:00:02 it returns message 501. The receiving client then issues a new request after 501, leaving another question waiting for the next message.
The response is still an HTTP response to a client request. The server is not sending an unsolicited second response on a completed exchange. If no message arrives before the configured timeout, it returns or closes according to the API contract, and the client reissues the request.
This avoids frequent empty replies when messages are sparse, but it keeps many requests outstanding and repeats the request lifecycle after each result or timeout. A gap between responses and new requests can be handled by querying durable history after the last ID. Choose server and proxy timeout settings together so an intermediary does not unexpectedly cut every held request short.
- 1 → 217:00:02 sendSender: event 501 → Chat API
- 2 → 3store before durable acceptanceChat API → Durable history 500,501
- 3 → 4new event 501Durable history 500,501 → Delivery gateway
- 4 → 5respond or stream by chosen transportDelivery gateway → Receiver: applied through 500
- 5 → 4connect/resume after 500Receiver: applied through 500 → Delivery gateway
- 4 → 3replay missing eventsDelivery gateway → Durable history 500,501
04WebSocket: a persistent full-duplex message channel
WebSocket establishes a persistent channel carrying messages in both directions. In the standard HTTP/1.1 opening sequence, the receiving client sends an HTTP request asking to upgrade to WebSocket. A successful server response uses status 101 and the protocol’s required validation headers. After that handshake, the peers exchange WebSocket frames rather than ordinary HTTP response bodies for each chat message. RFC 6455.
Arrow direction shows message direction. The SSE command arrow is a separate HTTP request.
Remember: WebSocket: both ways. SSE stream: server to client.
Try from memoryCan an SSE event stream itself carry client commands back to the server?
No. SSE streams server events to the client. The application normally sends commands in separate HTTP requests.
At 17:00:02, the gateway sends frame 501 to the receiving client without waiting for a new application request. At 17:00:02.100, the receiving client can send a typing or acknowledgment message back over the same channel. This full-duplex behavior is useful for frequent two-way interaction.
The 101 upgrade is specific to the HTTP/1.1 handshake above. RFC 8441 defines extended CONNECT for WebSocket over HTTP/2, and RFC 9220 adapts it for HTTP/3. Client, gateway, and intermediary support must agree; do not assume every deployed WebSocket connection uses the same handshake.
The browser’s Origin header identifies the web page’s scheme, host and port. A WebSocket server can use it to restrict which web applications may initiate browser connections, which matters when browsers attach session cookies. This check answers a different question from which user is signed in.
Use encrypted transport and validate browser Origin according to the allowed application origins, especially for cookie-authenticated connections. Origin checking is an additional browser security boundary, not a substitute for authenticating the user or authorizing each subscription and command.
05Server-sent events: a server-to-client HTTP stream
Server-sent events, or SSE, use an HTTP response that remains open while the server sends text events. The response has content type text/event-stream. Browser EventSource understands the event format and reconnect behavior. At 17:00:02 the server can send an event containing ID 501 and the new message; IDs can support resumption. The stream is UTF-8 text, so binary payloads need another representation or delivery path. HTML standard.
The receiving client does not send chat commands backwards through that response stream. The receiving client can use a separate ordinary HTTP POST to send a message while receiving new events through SSE. That can be a clean design when most live traffic flows from server to client.
The server must preserve or reconstruct events after a reconnect; EventSource remembering an event ID does not create history storage. Intermediaries also need streaming-compatible behavior. If a proxy buffers the response until it is large, the apparent “live” messages can arrive late in batches.
An SSE event sends id: 501, then data: {"messageId":501,"text":"hello"}, followed by a blank line. Native EventSource remembers that ID and sends Last-Event-ID on reconnect. But receipt does not prove an asynchronous handler finished processing and saving the event. If recovery must resume after saved work, track that position separately in an application cursor. Pass it through an acknowledgment endpoint or an application-controlled reconnect, and make the replay API use it.
06Compare transports by traffic, latency, and direction
| Technique | When 501 is delivered in the example | Main tradeoff |
|---|---|---|
| Five-second polling | Next request at 17:00:05 | Simple, but delay and empty requests |
| Long polling | Held request returns around 17:00:02 | Outstanding requests and repeated lifecycle |
| WebSocket | Server frame around 17:00:02 | Two-way channel with connection management |
| SSE | Streaming event around 17:00:02 | One-way live response; commands use another request |
For frequent typing, acknowledgments, and chat traffic, choose WebSocket here. The benefit is a convenient two-way channel with less repeated request framing. The cost is gateway connection state, reconnect handling, and operational limits. For an export-progress display with occasional client commands, SSE may be simpler. For a status page tolerating several seconds of delay, polling may be entirely sufficient.
A persistent channel still consumes sockets, memory, heartbeat traffic, and network capacity. Estimate those separately from requests/second. Moving from polling changes the resource profile; it does not make idle clients free.
A heartbeat is a small periodic message used to check whether a connection or peer remains responsive. It adds traffic even when users are idle, and a missed heartbeat is evidence for a timeout policy rather than proof of a crash. Include this background work when comparing persistent channels with polling.
As a separate capacity estimate, 100,000 open connections at an assumed 16 KiB of total connection and bounded-buffer state consume about 1.53 GiB. One application heartbeat per connection every 30 seconds adds about 3,333 heartbeat messages/s in that direction. These are workload assumptions to measure on the chosen gateway, not protocol constants. They show why replacing 20,000 idle polls/s changes costs rather than eliminating them.
07Reconnect, replay, and slow-consumer recovery
Suppose the receiving client receives 501 and the connection drops before the receiving client records progress. On reconnect the receiving client reports its last applied ID, possibly still 500. The service replays 501 from durable history. The receiving client deduplicates by message ID so it appears once. The cursor should describe what the client actually applied, not merely bytes sent by a gateway.
If 500 is older than retained history, return an explicit resynchronization path and fetch a snapshot or current history page. Do not silently skip the missing interval. Use heartbeats to detect broken paths when needed, and stagger reconnect retries with randomized delays so every client does not reconnect simultaneously after an outage.
Bound each client’s outgoing buffer. A phone receiving more slowly than events arrive cannot accumulate memory forever. Disconnect and resume, reduce optional updates, or send a fresh summarized state according to the product contract. Authenticate connections and authorize subscriptions; an already-open connection must also have a policy for credential expiration or access revocation.
08Interview answer: choose a transport for chat
Interviewer: “Should this chat use WebSockets?”
Candidate: “Because our chat has frequent two-way activity, I would use a WebSocket channel after authenticating the connection. But I would separate transport from delivery correctness. The sending client’s 501 goes into durable history; the receiving client reconnects with its last applied ID and deduplicates any replay.
“If this were only server-driven progress, SSE plus ordinary command requests would be a reasonable simpler alternative. Polling would be acceptable if we could tolerate its freshness interval and the idle request load. I would also specify proxy timeouts and bounded per-client buffers, because a persistent connection can still fail or fall behind.”
The answer explains direction, latency, overhead, and recovery using the same event. It avoids claiming that WebSocket itself supplies offline history, authorization, ordering across all services, or exactly-once business effects.
Practise the interview questions
Say your answer aloud before opening the model answer. Then answer the follow-up and compare the reasoning.
Compare short polling, long polling, SSE, and WebSocket. What does real-time mean for a chat application?
Reveal a model answer
For chat, define a freshness target such as new messages normally appearing within 300 ms; this is an illustrative product target, not a property automatically guaranteed by a transport. Short polling repeats a request on a timer, creating idle traffic and up to roughly one interval of waiting. Long polling holds a request until data arrives or it times out, then the client starts another. SSE keeps an HTTP response open for text events from server to client. WebSocket maintains a full-duplex framed message channel.
For infrequent notifications, polling may be sufficient. For mostly one-way live updates, SSE plus ordinary HTTP commands can be simple. For frequent chat messages, typing, and acknowledgments in both directions, WebSocket is a reasonable choice. All choices need authentication, bounded buffering, reconnect, and a durable cursor/history policy; the socket alone cannot restore missed messages.
Interviewer follow-up
Does every poll open a new TCP connection?
Reveal the follow-up answer
“No. Requests can reuse connections. I would distinguish request overhead from connection-handshake overhead in the estimate.”
What the answer must demonstrate: Separate application exchange lifecycle from underlying connection reuse.
100,000 clients poll every five seconds. An event arrives at :02 between polls at :00 and :05. Estimate idle QPS and event delay.
Reveal a model answer
“100,000 clients divided by a five-second interval produce 20,000 requests/s even without updates. An event at :02 waits three seconds until the :05 poll, plus network and processing time. Uniformly timed arrivals wait roughly half an interval on average.”
Interviewer follow-up
How would you reduce load?
Reveal the follow-up answer
“Increase the interval, reduce active polling when appropriate, or change the transport. A longer interval has a clear freshness cost.”
What the answer must demonstrate: State the arrival and interval assumptions.
What exactly is held during long polling?
Reveal a model answer
“The server holds one HTTP request until an update exists or the timeout expires. For example, a request after cursor 500 returns event 501, and the client immediately requests after its applied cursor again. The response may contain a batch; long polling means one response per request, not necessarily one event. History bridges the short gap before the next held request.”
Interviewer follow-up
Can a message arrive during the reconnect gap?
Reveal the follow-up answer
“Yes. The next request asks after the known ID, so durable history bridges the gap rather than relying on perfect timing.”
What the answer must demonstrate: Explain wait, response, reissue, and timeout.
Describe how the WebSocket channel begins.
Reveal a model answer
“For HTTP/1.1, the client requests an upgrade and the server validates it and returns 101 before exchanging WebSocket frames. HTTP/2 and HTTP/3 have extended-CONNECT mechanisms when supported. I would specify what our gateway and clients actually support, authenticate the session, validate browser Origin, and authorize subscriptions; protocol negotiation alone grants no user permission.”
Interviewer follow-up
Does a successful handshake guarantee message persistence?
Reveal the follow-up answer
“No. It establishes the channel. The application still needs a durable history and an acknowledgment/resume contract.”
What the answer must demonstrate: Handshake, authentication, and durability are distinct mechanisms.
Could the receiving client send messages while receiving SSE?
Reveal a model answer
“Yes. The receiving client can receive a continuing event-stream response and send commands through separate HTTP POST requests. SSE is one-way on that stream, not a prohibition on the browser making other requests. It is attractive when live traffic is primarily server-to-client.”
Interviewer follow-up
What happens to binary attachments?
Reveal the follow-up answer
“I would normally upload and retrieve them through a separate media path, using events to carry metadata or references.”
What the answer must demonstrate: One-way stream does not mean one-way application.
A client receives event 501 but reconnects with last-applied cursor 500. How should replay work?
Reveal a model answer
“Replay event 501 from durable history and apply it idempotently by message ID. Cursor 500 must mean the application applied every event through that position in the relevant stream. Native SSE Last-Event-ID can advance before the handler durably applies an event, so I would use the explicit application cursor for this stronger replay contract. A gateway writing bytes is not evidence that the recipient recorded the update.”
Interviewer follow-up
How do you avoid losing events between replaying history and switching to live delivery?
Reveal the follow-up answer
“Register a bounded live buffer first, record the latest committed event position H, replay after the client cursor through H, then deliver buffered events after H and continue live. Deduplicate overlap and preserve stream order. If history expired or the buffer overflows, require an explicit resynchronization instead of silently skipping the gap.”
What the answer must demonstrate: Connection delivery and application progress can differ.
How should a gateway handle a receiving client that consumes events slower than they arrive?
Reveal a model answer
“I bound the outgoing buffer. Depending on the event contract, I can drop optional typing updates, summarize state, or disconnect and resume durable messages later. I cannot let one slow client grow gateway memory without limit.”
Interviewer follow-up
Can I drop an undelivered durable message silently?
Reveal the follow-up answer
“Not if the product promised recoverable delivery. It must remain available through history and the resume path, or the client must be told the gap cannot be recovered.”
What the answer must demonstrate: Separate replaceable hints from durable events.
Why can a simultaneous reconnect after a gateway outage cause another outage?
Reveal a model answer
“A large connection outage can cause every client to reconnect and replay simultaneously. I would use randomized retry delays, admission control, and bounded replay work while protecting the history store. A healthy gateway fleet can still overload its shared dependencies during recovery.”
Interviewer follow-up
What access check happens on reconnect?
Reveal the follow-up answer
“Reauthenticate and reauthorize the requested subscriptions, including any changes while the client was offline.”
What the answer must demonstrate: Recovery traffic and permission changes are part of the protocol.
Blank-page exercise · 15 minutes
Build the answer yourself
Compare delivery from 17:00:00 to 17:00:06 using polling, long polling, SSE, and WebSocket. Event 501 becomes durable at 17:00:02. Then drop the connection after delivery but before applied progress is recorded, and specify replay behavior.
- Show who initiates every request or message.
- Calculate the polling delay and idle request rate.
- Explain opening/response behavior for WebSocket and SSE.
- Resume from the last applied event and deduplicate a replay.
Check that each component and design decision follows from your requirements and workload.
Recall the key ideas
Answer from memory before opening each card. Explain why the choice works and what it costs. Revisit missed cards tomorrow.
Real-time communication: polling, long polling, SSE, and WebSocketWhy does the receiving client’s five-second poll delay message 501?Recall first, then reveal
The event arrives at 17:00:02, but the next request is at 17:00:05.
Timer decides when to ask.
Return to lessonReal-time communication: polling, long polling, SSE, and WebSocketWhat happens after a long-poll response?Recall first, then reveal
The client immediately issues another request after its last received/applied cursor according to the API contract.
One response per request; then request again.
Return to lessonReal-time communication: polling, long polling, SSE, and WebSocketHow do WebSocket and SSE differ in direction?Recall first, then reveal
WebSocket carries messages both ways; SSE streams server-to-client events while client commands use another request.
Conversation versus broadcast response.
Return to lessonReal-time communication: polling, long polling, SSE, and WebSocketDoes reconnect automatically recover missing messages?Recall first, then reveal
Only if the application stores history, accepts a resume cursor, and handles duplicate replay.
Connection restored ≠ missed messages recovered.
Return to lessonFinal revision
Summary and interview notes
Choose polling, SSE or WebSocket from the allowed delay, message direction and connection cost. To recover missed messages, save history, remember what the client applied, join replay to live updates without a gap, and limit data buffered for slow clients.
Remember these points
- Polling trades a chosen delay for repeated idle requests; long polling waits within each request and then reissues it.
- SSE streams UTF-8 text from server to client; WebSocket provides a bidirectional framed channel.
- Native EventSource Last-Event-ID records transport progress, not a durable application acknowledgment.
- A resume cursor must mean that every event up to that position has been processed and recorded in that stream; seeing a later event is not enough.
- Connection count, memory, heartbeat traffic, and replay bursts need capacity limits even when request QPS falls.
Interview tips
- Use one event-arrival time to compare all four transports and calculate the idle polling load.
- Draw the reconnect failure after delivery but before application progress is saved.
- Explain how history replay meets live delivery without an unobserved gap.
Important qualifications
- WebSocket 101 Upgrade describes HTTP/1.1; HTTP/2 and HTTP/3 use their negotiated extended-CONNECT mechanisms.
- Browser Origin validation complements authentication and subscription authorization; an open connection does not keep permissions valid forever.
- The 16 KiB connection-state and 30-second heartbeat estimates are illustrative and must be measured for the selected gateway.
Technical references
- RFC 6455: The WebSocket ProtocolVerified protocol source for the HTTP/1.1 opening handshake, framing, and bidirectional channel.
- HTML Standard: Server-Sent EventsVerified standard for EventSource, UTF-8 event-stream format, event IDs, and reconnect behavior.
- RFC 8441: Bootstrapping WebSockets with HTTP/2Extended CONNECT, distinguishing an HTTP/2 WebSocket setup from the HTTP/1.1 101 upgrade.
- RFC 9220: Bootstrapping WebSockets with HTTP/3HTTP/3 WebSocket setup; actual endpoint/intermediary support must be verified.
Practice marks stay in this browser.