Skip to content

⚡ Real-time - WebSockets vs. SSE

The Senior Mindset: Real-time communication is a “Stateful” problem in a “Stateless” world. A senior engineer prioritizes Server-Sent Events (SSE) for unidirectional updates due to its simplicity and only reaches for WebSockets when full-duplex (two-way) communication is strictly necessary.


SSE is a standard allowing servers to push data to web pages over HTTP. It is essentially a long-lived HTTP connection where the server keeps the response open.

  • Unidirectional: Server → Client only.
  • Protocol: Standard HTTP. Works over HTTP/1.1 and is even better over HTTP/2.
  • Automatic Reconnection: Browsers handle reconnections natively.
  • Ease of Use: Simple to implement on both backend (text/event-stream) and frontend (EventSource API).
  • Live score updates.
  • Social media news feeds.
  • System notifications or status progress bars.

A distinct protocol (built over TCP) that provides a persistent, full-duplex connection between client and server.

  • Bi-directional: Server ↔ Client. Both can send data at any time.
  • Stateful: The server must keep an open socket for every connected user.
  • Binary Support: Can send both text and binary data efficiently.

When you move from one server to a cluster, real-time connections become difficult because Client A might be connected to Server 1, but the event they need is triggered on Server 2.

To synchronize messages across multiple backend instances, you need a message broker (usually Redis).

  • Process: When an event occurs on Server 2, it publishes a message to a Redis channel. Server 1 (and all other instances) is subscribed to that channel and pushes the message to its connected clients.

Since WebSockets start with an HTTP handshake, your Load Balancer must support Session Affinity (Sticky Sessions). This ensures the handshake and the subsequent protocol upgrade happen on the same physical server.

The OS has a limit on “Open File Descriptors.” Each WebSocket counts as one.

  • Senior Tip: You may need to tune the ulimit on your Linux servers or use a specialized proxy like HAProxy or Nginx to handle tens of thousands of concurrent connections.

FeatureSSEWebSockets
DirectionOne-way (Server to Client)Two-way (Bi-directional)
ProtocolStandard HTTPWS Protocol (Upgrade)
ReconnectionNative / AutomaticManual implementation required
Firewall FriendlyYes (standard port 80/443)Can be blocked by strict proxies
Max ConnectionsLimited by browser (6 per domain)Limited by server resources

Network intermediaries (firewalls, load balancers) often kill “idle” connections.

  • Senior Solution: Implement a “Heartbeat” where the server or client sends a tiny packet every 30 seconds to prove the connection is still alive.

You cannot send custom headers with the standard browser WebSocket API.

  • Workaround: Pass the JWT/Token as a Query Parameter (less secure, appears in logs) or perform a “Ticket-based” authentication:
    1. Client requests a short-lived “ticket” via a REST POST.
    2. Server returns a UUID.
    3. Client connects to WS via ws://api.com?ticket=UUID.

💡 Seniority Note: “Real-time” doesn’t always mean “WebSockets.” If your data updates every 10 seconds, Long Polling or even Short Polling with aggressive caching might be 10x cheaper to run and 100x easier to maintain than a WebSocket cluster.


  • [[Protocols-TCP-UDP-WebSockets]]
  • [[Messaging-Redis-PubSub]]
  • [[Architecture-Load-Balancing]]