Realtime Communication

Push updates to users the moment they happen: polling, long polling, server-sent events and WebSockets, and how open connections reshape the design.

15 minLesson 5 of 6
On this page
  1. The idea
  2. How open connections change the design
  3. Numbers worth remembering
  4. In the interview
  5. Common mistakes
  6. What to practise next

A chat app has 1 million people with the app open. To see new messages, each phone asks the server "anything new?" every 5 seconds. That is 1,000,000 ÷ 5 = 200,000 requests a second. About 2,000 new messages arrive a second in total, so at most 2,000 of those 200,000 answers carry anything: 99% of the work returns "no". And a message still waits 2.5 seconds on average before anyone sees it.

The fix is to turn the direction around: keep a connection open and let the server speak first. That is cheap for the network and expensive for your architecture, because now your servers remember who is connected to them.

The idea

HTTP is built for the client to ask and the server to answer. Realtime features need the server to send when something happens. There are four ways to get there, from "ask often" to "hold a two-way pipe open":

  • Short polling: the client asks on a timer.
  • Long polling: the client asks, and the server holds the request open until there is news or about 30 seconds pass. Then the client asks again at once. Messages that arrive between two polls must be fetched with a cursor ("everything after message 9001"), or they are missed.
  • Server-sent events (SSE): one HTTP response that never ends; the server writes events into it as they happen. One direction only, server to client, text only. Browsers reconnect automatically and send the last event id they saw, so a server that tags events with ids can resume.
  • WebSocket: starts as an HTTP request asking to upgrade, then becomes a two-way channel of messages over the same TCP connection. Nothing is built in for reconnecting or replaying missed messages; you write that.
Getting updates from server to client
OptionGood atBad atPick it when
Short pollingPlain HTTP requests; works with every cache, proxy and server.Mostly empty responses, and updates arrive up to one interval late.Updates are rare and a delay is fine: a report finishing, every 30 seconds.
Long pollingNear-instant delivery over plain HTTP, through any proxy.A new request after every message, and gaps between polls need a cursor.A fallback where WebSockets and SSE are blocked.
Server-sent eventsSimple server push over HTTP, with reconnect and resume built into browsers.Server to client only. On HTTP/1.1, browsers cap open connections per host at a handful.One-way feeds: notifications, live scores, streaming text.
WebSocket Usual defaultLow-overhead messages both ways over one connection.You build heartbeats, reconnects and replay yourself; some networks block it.Two-way and frequent: chat, multiplayer, collaborative editing.

For chat, pick WebSockets: both sides talk often. Pick SSE when the client only listens. Keep short polling for things that change every few minutes; a million open connections for one update an hour is waste too.

How open connections change the design

With request and response, any server can answer any request. With a WebSocket, Ben's connection lives on one particular server for hours. When Ana sends Ben a message, it lands on Ana's server, and something must get it to Ben's. That one fact reshapes the system:

  • Connection servers become their own tier. They hold sockets and pass messages through, nothing else, so business logic can be deployed without dropping a million connections.
  • Pub/sub routes messages between servers. When Ben connects, his server subscribes to a channel user:ben. Anyone with a message for Ben publishes to that channel. The alternative is a registry ("Ben is on server 7") in a shared store. Pub/sub keeps that registry for you: a dead server's subscriptions vanish with it.
  • The database stays the source of truth. Basic pub/sub delivers only to whoever is subscribed at that moment, at most once. Store the message first, so a client that was offline can catch up.
Connection servers hold the sockets. Messages go to the chat service to be stored, then through pub/sub to whichever connection server holds the recipient.Phones and browsers and Load balancer (WebSocket); Load balancer and Connection servers; Connection servers to Chat service (new message); Chat service to Message store (store); Chat service to Pub/sub (publish); Pub/sub to Connection servers (deliver).Phones andbrowsersLoad balancerConnectionserversPub/subChat serviceMessage storeWebSocketnew messagestorepublishdeliver
Connection servers hold the sockets. Messages go to the chat service to be stored, then through pub/sub to whichever connection server holds the recipient.
Ana messages Ben, then Ben's server diesUse the arrows or ← → keys
  1. Ana messages Ben, then Ben's server dies, step 1Ana and Conn server 1; Ben and Conn server 2; Ben and Conn server 1; Conn server 1 to Chat service; Chat service to Message store; Chat service to Pub/sub; Pub/sub to Conn server 2.AnaBenConn server 1Conn server 2sub user:benChat servicePub/subMessage store

    1Ana's socket is on server 1 and Ben's on server 2. When Ben connected, server 2 subscribed to user:ben.

  2. Ana messages Ben, then Ben's server dies, step 2Ana and Conn server 1; Ben and Conn server 2; Ben and Conn server 1; Conn server 1 to Chat service; Chat service to Message store; Chat service to Pub/sub; Pub/sub to Conn server 2.AnaBenConn server 1Conn server 2Chat servicePub/subMessage store
    last id Ben saw
    9000

    2Ana sends "lunch?" over her open socket: no new connection, no handshake.

  3. Ana messages Ben, then Ben's server dies, step 3Ana and Conn server 1; Ben and Conn server 2; Ben and Conn server 1; Conn server 1 to Chat service; Chat service to Message store; Chat service to Pub/sub; Pub/sub to Conn server 2.AnaBenConn server 1Conn server 2Chat servicePub/subMessage store9001 stored
    last id Ben saw
    9000

    3Server 1 hands it to the chat service, which stores it as message 9001 before anything else. If delivery fails later, the message still exists.

  4. Ana messages Ben, then Ben's server dies, step 4Ana and Conn server 1; Ben and Conn server 2; Ben and Conn server 1; Conn server 1 to Chat service; Chat service to Message store; Chat service to Pub/sub; Pub/sub to Conn server 2.AnaBenConn server 1Conn server 2Chat servicePub/subuser:benMessage store
    last id Ben saw
    9000

    4The chat service publishes 9001 to user:ben. It does not need to know which server Ben is on.

  5. Ana messages Ben, then Ben's server dies, step 5Ana and Conn server 1; Ben and Conn server 2; Ben and Conn server 1; Conn server 1 to Chat service; Chat service to Message store; Chat service to Pub/sub; Pub/sub to Conn server 2.AnaBenConn server 1Conn server 2Chat servicePub/subMessage store
    last id Ben saw
    9001

    5Server 2 is the only subscriber to that channel, so it receives 9001 and pushes it down Ben's socket.

  6. Ana messages Ben, then Ben's server dies, step 6Ana and Conn server 1; Ben and Conn server 2; Ben and Conn server 1; Conn server 1 to Chat service; Chat service to Message store; Chat service to Pub/sub; Pub/sub to Conn server 2.AnaBenConn server 1Conn server 2downChat servicePub/subno subscriberMessage store9002 stored
    last id Ben saw
    9001

    6Server 2 crashes. Ben's socket drops, and nobody is subscribed to user:ben any more. Ana's next message, 9002, is stored, but the publish reaches no one.

  7. Ana messages Ben, then Ben's server dies, step 7Ana and Conn server 1; Ben and Conn server 2; Ben and Conn server 1; Conn server 1 to Chat service; Chat service to Message store; Chat service to Pub/sub; Pub/sub to Conn server 2.AnaBenConn server 1sub user:benConn server 2downChat servicePub/subMessage store
    last id Ben saw
    9001

    7Ben's app waits a random 0 to 30 seconds, then reconnects through the load balancer and lands on server 1. Server 1 subscribes to user:ben before the app asks for history, so nothing can slip between the two.

  8. Ana messages Ben, then Ben's server dies, step 8Ana and Conn server 1; Ben and Conn server 2; Ben and Conn server 1; Conn server 1 to Chat service; Chat service to Message store; Chat service to Pub/sub; Pub/sub to Conn server 2.AnaBenConn server 1Conn server 2downChat servicePub/subMessage storeafter 9001
    last id Ben saw
    9002

    8The app sends "give me everything after 9001". The store returns 9002, and Ben misses nothing. The app drops any id it already has. The store, not pub/sub, made delivery reliable.

1 / 8

The random wait in step 7 matters. Server 2 may have held 50,000 sockets. If all reconnect in the same second, they hit the rest of the fleet like a small attack. Spread over 30 seconds, it is 50,000 ÷ 30 ≈ 1,700 a second.

Long-lived connections bring two chores. Heartbeats: send a small ping every 30 seconds or so, because a phone that loses signal does not close its socket, and idle connections get cut by proxies. Deploys: drain a server by telling clients to reconnect elsewhere, a slice at a time, instead of killing it with everyone attached.

Numbers worth remembering

  • Polling load = users ÷ interval in seconds.
  • An idle connection costs memory, not CPU. Assume a scenario number such as 50,000 per server and say you would load test it.
  • Heartbeat load = connections ÷ heartbeat interval: 2 million connections pinging every 30 seconds is about 67,000 small messages a second.
Estimate: Connection servers for a chat app

How many connection servers do you need for the peak number of open connections?

You know
  • 10 million daily active users
  • At peak, 20% of them have the app open
  • Assume 50,000 connections per server

Show the working
  1. Open connections at peak: 10 million × 0.2 = 2 million
  2. Servers: 2,000,000 ÷ 50,000 = 40
  3. Add spare capacity so one dying server's clients have somewhere to go

Estimate 40 (anything from 15 to 120 is a good answer)

In the interview

Bring this up as soon as a requirement says "instantly", "live" or "as it happens": chat, notifications, a driver's position, a shared document. Pick the transport, then spend your time on the hard part, which is routing and recovery. Phrases that show judgement: "Users both send and receive, so WebSockets." "Connection servers are stateful, so I keep them thin." "Pub/sub is fire-and-forget, so the store is the truth and clients resync by last message id."

Routing a messageWeak answer
Interviewer

How does a message reach the recipient?

You

The server sends it over the recipient's WebSocket.

Routing a messageStrong answer
Interviewer

How does a message reach the recipient?

You

The sender's connection server passes it to the chat service, which stores it and publishes to the recipient's channel. Whichever connection server holds the recipient is subscribed and pushes it down. If they're offline, nobody's subscribed, and they fetch it from the store by last id when they reconnect.

Follow-ups to expect:

  • "A user has a phone and a laptop." Two connections, possibly on two servers, both subscribed to the same user channel, so both get the message.
  • "How do you balance WebSocket traffic?" Least connections, long idle timeouts on the balancer, and draining on deploy.
  • "Are messages in order?" Within one conversation, yes: the store gives each message the next id in that conversation and clients sort by it. Global order is not needed.
  • "What if a publish is lost while Ben is online?" His app sees a gap, 9003 after 9001, and fetches 9002 from the store. A lost last message leaves no gap, so apps also sync when opened.

Common mistakes

Quick check

300,000 users keep a dashboard open that polls every 10 seconds. How many requests a second is that?

A sports site shows live scores in the browser. Readers never send anything back. Which transport fits best?

A connection server holding 60,000 sockets dies. Clients wait a random 0 to 30 seconds before reconnecting. About how many reconnects a second hit the other servers?

What to practise next

Open connections invite abuse and floods, which is where Rate Limiting comes in. To put all of this into a full design, work through Design a Chat App.