Real-Time Communication: WebSockets, SSE, and Long Polling Explained
The Problem HTTP Was Never Designed to Solve
π WebSockets = bidirectional persistent channel β use for chat, gaming, collaborative editing.
π― System Scenario & Requirements
System Goal
π WebSockets = bidirectional persistent channel β use for chat, gaming, collaborative editing.
Actors & Components
- Application or API tier
- Core service under design
- Operator or SRE observer
Functional Requirements
- TLDR: π WebSockets = bidirectional persistent channel β use for chat, gaming, collaborative editing.
- SSE = one-way server push over HTTP with built-in reconnect β use for AI streaming, live logs, notifications.
- Long Polling = held HTTP requests β the pragmatic fallback when WebSockets are blocked.
Constraints & Assumptions
- Failure modes to plan for: WebSocket connection loss at scale.
- Mobile networks and corporate proxies aggressively terminate connections that appear idle.
β‘ Execution Stages & Decision Trace
Stage 1 β How Each Pattern Delivers Data in Practice
Short Polling: The Simplest Approach That Doesn't Scale Short Polling is the default mental model for most engineers: the client sends a regular HTTP GET on a timer and immediately receives whatever data is available ββ¦
In practice, a polling client sends a regular GET /api/notifications HTTP request every few seconds.
Deep Dive
Scenario context
π WebSockets = bidirectional persistent channel β use for chat, gaming, collaborative editing. SSE = one-way server push over HTTP with built-in reconnect β use for AI streaming, live logs, notifications. Long Polling = held HTTP requests β the pragmatic fallback when WebSockets are blocked. Short Polling = simplest but most wasteful β only for low-frequency, low-traffic scenarios. The decisive question is always:β¦
This walkthrough focuses on The Problem HTTP Was Never Designed to Solve.
Before making a design choice, clarify:
- When you type a message in Slack and it appears instantly on your colleague's screen in Tokyo, that's not magic β it's a persistent WebSocket connection that stays open between your browser and Slack's servers.
- But when you check Twitter's notification bell, it doesn't use WebSockets β it uses Long Polling.
- And ChatGPT's streaming responses use a third approach entirely: Server-Sent Events.
Concepts in play: system-design-hld-architectures, api-gateway, api-security-oauth2, caching
Stage 1 β How Each Pattern Delivers Data in Practice
- Short Polling: The Simplest Approach That Doesn't Scale Short Polling is the default mental model for most engineers: the client sends a regular HTTP GET on a timer and immediately receives whatever data is available ββ¦
- In practice, a polling client sends a regular GET /api/notifications HTTP request every few seconds.
- In the vast majority of calls β 99% or more when notifications are infrequent β the server responds immediately with an empty events array.
- Only occasionally does a response carry actual event data.
flowchart TD
Driver["Driver Node"]
Planner["Query Planner"]
Optimizer["Catalyst Optimizer"]
Executor["Executor Task"]
Driver -->|"Process Flow"| Planner
Planner --> Optimizer
Optimizer -->|"Optimized Plan"| Executor
Executor -->|"Result"| Driver
Observable outcome: Only occasionally does a response carry actual event data.
Stage 2 β Deep Dive: Connection State, Internals, and Protocol Costs
- The Internals: What the Server Actually Holds Each pattern has a fundamentally different server-side resource profile, and choosing the wrong one for your scale can break production.
- Any HTTP server handles it natively β no persistent state, no special infrastructure.
- The cost is pure throughput: CPU, bandwidth, and request-handling capacity consumed proportionally to polling frequency.
- Long Polling requires the server to hold the HTTP response object in memory for each waiting client.
Observable outcome: Long Polling requires the server to hold the HTTP response object in memory for each waiting client.
Stage 3 β Connection Lifecycle: Seeing All Four Patterns Side by Side
- Reading the diagram: Short Polling and Long Polling both use repeated HTTP requests β the only difference is how long the server waits before responding.
- SSE opens a single HTTP stream that the server continuously writes to, with the client as a passive reader.
- WebSockets are the only pattern where the client and server each hold a write handle simultaneously β the bidirectional arrow is the defining architectural distinction.
- Why connection lifetime matters: Every new HTTP connection pays a TCP + TLS handshake cost (~3 round trips for TLS 1.3).
graph LR
subgraph SP[ Short Polling]
C1[Client] -->|GET every N seconds| S1[Server]
S1 -->|Instant response empty or data| C1
end
subgraph LP[ Long Polling]
C2[Client] -->|GET /updates| S2[Server]
S2 -->|Held open responds only when data ready| C2
end
subgraph SSE_[ Server-Sent Events]
C3[Client] -->|GET /stream Accept: text/event-stream| S3[Server]
S3 -->|Persistent stream server writes events continuously| C3
end
subgraph WS_[ WebSockets]
C4[Client] -->|HTTP GET + Upgrade: websocket| S4[Server]
S4 -->|101 Switching Protocols| C4
C4 <-->|Full-duplex framed messages either side writes any time| S4
end
Observable outcome: Why connection lifetime matters: Every new HTTP connection pays a TCP + TLS handshake cost (~3 round trips for TLS 1.3).
Stage 4 β Real-World Applications: Who Uses WebSockets, SSE, and Long Polling in Production
- Every active Slack session maintains a persistent WebSocket.
- Messages, typing indicators, read receipts, and presence heartbeats all transit the same channel.
- Slack's backend routes WebSocket frames through a Redis pub/sub layer so that when Alice's message arrives on Server A, it fans out to Bob's connection on Server B.
- The bidirectionality of WebSockets is essential β the client sends typing events and ACKs back to the server over the same connection.
Observable outcome: The bidirectionality of WebSockets is essential β the client sends typing events and ACKs back to the server over the same connection.
Stage 5 β Socket.IO: Intelligent Fallback for Any Environment
- Socket.IO is the most widely used real-time library for Node.js.
- Its core value is automatic transport negotiation : it attempts a WebSocket upgrade first, falls back to HTTP Long Polling if WebSockets are blocked (by a proxy or CDN), and degrades further if needed β transparently, wβ¦
- This makes it the pragmatic choice for public-facing applications where you cannot control every client network environment.
- Socket.IO also layers on rooms (named broadcast groups), namespaces (logical sub-connections), built-in exponential-backoff reconnect, and acknowledgment callbacks β infrastructure you would otherwise write yourself.
Observable outcome: Socket.IO also layers on rooms (named broadcast groups), namespaces (logical sub-connections), built-in exponential-backoff reconnect, and acknowledgment callbacks β infrastructure you would otherwise write yourself.
Stage 6 β Designing a Live Notification System
- Scenario: A project management tool (similar to Linear or Jira) needs to deliver real-time notifications to users when a task is assigned, a comment is posted, or a sprint is kicked off.
- Traffic profile: 200,000 active users, averaging 5 notifications per user per hour, with bursts of 10,000 notifications in 10 seconds when a sprint launches.
- Pattern Selection Walkthrough Verdict: Server-Sent Events.
- Each authenticated user opens one EventSource('/api/notifications/stream') connection.
Observable outcome: Each authenticated user opens one EventSource('/api/notifications/stream') connection.
End-to-end outcome
After working through the stages, you should be able to explain:
- Don't reach for WebSockets by default.
- The most common mistake is defaulting to WebSockets because they feel "more real-time." WebSockets are the right tool for bidirectional workloads.
Alternatives considered
Decision Guide: Choosing the Right Real-Time Protocol
Start at the bidirectional question every time.
Failure and degraded modes
Trade-offs & Failure Modes: Why Each Real-Time Pattern Has a Price
- Detection: Failure modes to plan for: WebSocket connection loss at scale.
- User or operator impact: Failure modes to plan for: WebSocket connection loss at scale.
