Skip to content
QuizMaker logoQuizMaker
Activity
System Design: The Complete Guide
5. Advanced Concepts & Patterns
1. Introduction to System Design
2. Vertical vs Horizontal Scaling
3. Load Balancing
4. Caching Strategies
5. CDNs (Content Delivery Networks)
6. SQL vs NoSQL
7. Database Sharding & Partitioning
8. The CAP Theorem
9. Microservices Architecture
10. Message Queues & Event Streaming
12. Design BookMyShow (Ticket Booking)
14. Design Dropbox (Cloud File Storage)
15. How to Approach Any System Design Interview
16. Back-of-the-Envelope Estimation
17. Consistent Hashing
18. Bloom Filters & Probabilistic Data Structures
19. Database Replication
20. Leader Election & Consensus (Raft & Paxos)
21. Distributed Transactions (Saga, 2PC, Outbox)
22. Event Sourcing & CQRS
23. Unique ID Generation at Scale
24. Rate Limiting Algorithms
25. Circuit Breakers & Bulkhead Pattern
26. API Gateway, Proxies & Service Mesh
27. Real-Time Communication
28. Observability (Tracing, Logging, SLOs)
30. Design a Chat System (WhatsApp)
31. Design YouTube (Video Streaming)
32. Design a Web Crawler
CONTENTS

27. Real-Time Communication

Polling, long polling, SSE, and WebSockets — how to push data to clients in real time.

Mar 5, 202619 views0 likes0 fires
18px

[!NOTE] HTTP is a request-response protocol — the client asks, the server answers. But many features need the server to push data to the client without being asked: chat messages, live scores, stock prices, notifications. This chapter covers four approaches to real-time communication, from simple to sophisticated.

The Four Approaches

MethodHow It WorksLatencyServer LoadBidirectional?
Short PollingClient asks "Any updates?" every N secondsUp to N secondsHigh (constant requests)No
Long PollingClient asks, server holds connection until there is dataNear-instantMedium (held connections)No
Server-Sent Events (SSE)Server pushes events over a persistent HTTP connectionNear-instantLowNo (server → client only)
WebSocketFull-duplex connection after HTTP upgrade handshakeInstantLow per message, but connection management overheadYes

Short Polling

Client: GET /api/messages?since=12345     → Server: [] (empty)
   ... 5 seconds later ...
Client: GET /api/messages?since=12345     → Server: [] (empty)
   ... 5 seconds later ...
Client: GET /api/messages?since=12345     → Server: [{id: 12346, text: "Hi!"}]

Simple but wasteful. If you poll every 5 seconds with 1 million connected users, that is 200,000 requests/second — most returning empty responses.

Long Polling

Client: GET /api/messages?since=12345
   ... Server holds the connection open ...
   ... 30 seconds of waiting ...
   ... A new message arrives! ...
Server: [{id: 12346, text: "Hi!"}]
Client: GET /api/messages?since=12346     → (immediately reconnects)

Much more efficient than short polling. The server only responds when there is actual data. Used by early Facebook chat and many notification systems.

Server-Sent Events (SSE)

A persistent, one-directional HTTP connection where the server pushes events to the client. The client opens a connection, and the server sends events as they occur:

Client: GET /api/events (Accept: text/event-stream)
Server: data: {"type": "message", "text": "Hello"}\n\n
   ...
Server: data: {"type": "message", "text": "World"}\n\n
   ...
(Connection stays open)

Pros: Built into every browser (EventSource API), automatic reconnection, works through standard HTTP infrastructure (proxies, CDNs). Con: Server-to-client only — client cannot send data back over the same connection.

Use case: Live dashboards, stock tickers, GitHub Actions build logs, notification feeds.

WebSocket

A true full-duplex, bidirectional connection. The client initiates an HTTP request with an Upgrade: websocket header. If the server agrees, the connection is "upgraded" to WebSocket protocol (ws:// or wss://).

Client → Server:  GET /chat HTTP/1.1
                  Upgrade: websocket
                  Connection: Upgrade

Server → Client:  HTTP/1.1 101 Switching Protocols
                  Upgrade: websocket

   ... now both sides can send messages at any time ...

Client: {"type": "message", "text": "Hello"}
Server: {"type": "message", "text": "Hi back!"}
Server: {"type": "typing", "user": "Alice"}
Client: {"type": "message", "text": "What''s up?"}

Scaling WebSockets with Redis Pub/Sub

With 1 million concurrent connections across 20 WebSocket servers, how does a message from User A (on Server 3) reach User B (on Server 7)?

User A → [WS Server 3] → PUBLISH to Redis → All WS servers subscribe
                                             → [WS Server 7] → User B

Redis pub/sub acts as a broadcast bus. When Server 3 receives a message, it publishes to a Redis channel. All 20 servers are subscribed and forward the message to the correct local connections.

Real-World Usage

  • Slack: WebSockets for real-time messaging. Falls back to long polling for restrictive corporate networks.
  • Uber: WebSockets for live driver location streaming to the rider''s phone. The driver sends GPS coordinates over WebSocket; the server fans them out.
  • GitHub: SSE for live build logs and notification updates. WebSocket for Codespaces terminal sessions.

Common Mistakes

  • ❌ Using WebSocket when SSE is sufficient — if you only need server-to-client updates (dashboard, notifications), SSE is simpler and works better with HTTP/2.
  • ❌ Forgetting reconnection logic — WebSocket connections drop frequently (mobile networks, proxy timeouts). Always implement auto-reconnect with backoff.
  • ❌ Putting all connections on one server — use Redis pub/sub or a message broker to fan out events across multiple WebSocket servers.
  • ❌ Not implementing heartbeats — without periodic ping/pong frames, dead connections hang forever. Use 30-second heartbeat intervals.

Scaling WebSocket: Multi-Server Architecture

                [Load Balancer]
                (sticky sessions by user_id)
                /        |        \
        [WS Server 1] [WS Server 2] [WS Server 3]
        (users A,B)   (users C,D)   (users E,F)
                \        |        /
                [Redis Pub/Sub]
                (broadcast channel)

  
    
    
  

When user A sends message to user D:

WS Server 1 receives message from user A
WS Server 1 publishes to Redis channel "chat:room:123"
WS Server 2 (subscribed) receives via Redis
WS Server 2 pushes to user D''s WebSocket connection

Connection Capacity Planning

Server ConfigMax ConnectionsMemory per Connection
Node.js (1 core, 1GB RAM)~10,000-50,000~20 KB
Go (1 core, 1GB RAM)~100,000-500,000~4 KB
Erlang/Elixir (Phoenix)~1,000,000-2,000,000~2 KB

Discord''s approach: Discord handles ~5 million concurrent WebSocket connections using Elixir/Erlang (BEAM VM), which excels at massive concurrent connections due to its lightweight process model.

[!TIP] Key Takeaways:
• Short polling: simple but wasteful. Only for low-frequency, non-critical updates.
• Long polling: good middle ground, used by early chat systems.
• SSE: best for server-to-client streams (dashboards, logs, notifications). Built-in browser support.
• WebSocket: the only option for bidirectional real-time communication (chat, gaming, collaboration).
• Scale WebSockets using Redis pub/sub + sticky sessions. Consider Go or Elixir for high connection counts.

Share this article

Share on TwitterShare on LinkedInShare on FacebookShare on WhatsAppShare on Email

Test your knowledge

Take a quick quiz based on this chapter.

mediumSystem Design
Quiz: Real-Time Communication
5 questions5 min

Continue Learning

28. Observability (Tracing, Logging, SLOs)

Intermediate
14 min

30. Design a Chat System (WhatsApp)

Advanced
18 min

31. Design YouTube (Video Streaming)

Advanced
18 min
Lesson 11 of 12 in 5. Advanced Concepts & Patterns
Previous in 5. Advanced Concepts & Patterns
26. API Gateway, Proxies & Service Mesh
Next in 5. Advanced Concepts & Patterns
28. Observability (Tracing, Logging, SLOs)
← Back to System Design: The Complete Guide
Back to System Design: The Complete GuideAll Categories