WebSocket vs SSE
WebSocket (RFC 6455) upgrades an HTTP/1.1 connection to a persistent, bidirectional binary channel. SSE (the EventSource API) uses a long-lived HTTP response with Content-Type: text/event-stream where the server pushes newline-delimited events. SSE is essentially free – it's plain HTTP, works through proxies, supports HTTP/2 multiplexing, and has built-in reconnection. WebSocket requires the Upgrade handshake, a separate protocol framing layer, and application-level reconnection logic.
WebSocket is a full-duplex binary protocol – both client and server can send messages at any time. SSE (Server-Sent Events) is a half-duplex HTTP protocol – only the server pushes data; client-to-server communication uses separate HTTP requests. SSE is simpler, works over plain HTTP/2, and automatically reconnects. WebSocket is needed for true bidirectional, low-latency communication.
| Feature | WebSocket | SSE |
|---|---|---|
| Direction | Full-duplex – client and server send simultaneously | Half-duplex – server pushes, client sends via new HTTP requests |
| Protocol | WebSocket (RFC 6455) – separate from HTTP after upgrade | HTTP (text/event-stream) – standard HTTP response |
| Data format | Binary frames or text – any payload | UTF-8 text only – structured as id/event/data fields |
| HTTP/2 compatibility | Requires HTTP/1.1 Upgrade – not HTTP/2 native | Works natively over HTTP/2 (multiplexed stream) |
| Auto-reconnect | No – application must implement reconnection logic | Yes – browser EventSource reconnects automatically using Last-Event-ID |
| Browser support | Universal (all modern browsers) | Universal except legacy IE (polyfill available) |
| Proxy/firewall | Some proxies buffer or block WebSocket connections | Works through all HTTP proxies – it's a plain HTTP response |
| Max connections | Separate connection per tab/worker | 6 per origin (HTTP/1.1) – unlimited with HTTP/2 multiplexing |
| Overhead per message | 2–14 byte frame header | Variable – text prefix + newlines (~20 bytes typical) |
| Use case fit | Chat, gaming, collaborative editing, trading terminals | Live feeds, notifications, dashboards, log streaming |
When to use WebSocket
WebSocket is the right choice when the client needs to send frequent messages to the server: chat applications, multiplayer games, collaborative document editing (like Figma or Google Docs), live trading platforms, and any scenario where bidirectional, low-latency messaging is required.
When to use SSE
SSE is the right choice for server-to-client data push where the client is largely passive: notification streams, live dashboards, real-time analytics, log tailing, stock tickers, and server-sent progress updates. SSE's automatic reconnection and HTTP/2 compatibility make it the lower-complexity choice for many use cases.
Common Mistakes
- Using WebSocket when SSE would work – SSE is simpler, auto-reconnects, works through proxies, and runs over HTTP/2. If the client doesn't need to push data, SSE is almost always the better choice.
- Not implementing reconnection logic for WebSocket – unlike SSE, WebSocket connections don't auto-reconnect. Production apps need exponential backoff reconnection with Last-Message-ID tracking.
- Expecting WebSocket to work through all enterprise proxies – many corporate HTTP proxies don't understand the Upgrade header and break WebSocket connections. SSE works through any HTTP proxy.
- Using SSE over HTTP/1.1 with many browser tabs – HTTP/1.1 limits 6 connections per origin; each SSE stream uses one. Switch to HTTP/2 where SSE streams are multiplexed over a single connection.
- Sending binary data over SSE – SSE is UTF-8 text only. Binary data must be base64-encoded, adding ~33% overhead. For binary streaming, WebSocket is correct.
FAQ
Can SSE replace WebSocket for a chat application?
Partially. With SSE, the server pushes incoming messages to all clients. But to send a message, the client makes a separate POST request. This works fine and many production chat systems use this model. The trade-off: each user message requires a full HTTP request/response cycle instead of a WebSocket frame. For low-frequency messaging this is acceptable; for high-frequency sub-100ms messaging, WebSocket wins.
Does WebSocket work over HTTP/2?
HTTP/2 WebSocket (RFC 8441) exists via CONNECT bootstrapping but is not widely deployed. Most WebSocket connections still use HTTP/1.1 with the Upgrade header. If you need WebSocket over HTTP/2, check your specific server and client library support. For most cases, WebSocket over HTTP/1.1 and SSE over HTTP/2 is the practical deployment model.
What is the difference between SSE and long-polling?
Long-polling opens an HTTP request, the server holds it open until it has data (or times out), sends a response, and the client immediately opens a new request. SSE opens a single HTTP connection and the server sends multiple events over it without closing. SSE is more efficient – no repeated handshake overhead, lower server resources, and the browser handles reconnection automatically.