Traffic and messaging
SSE and WebSockets
Server-Sent Events push a one-way stream over plain HTTP with built-in resume, WebSockets give full-duplex frames, and WebTransport adds streams and datagrams over HTTP/3. Choose by direction and message rate.
Two transports let the server push to the client over one long-lived connection. Server-Sent Events (SSE) send a one-way stream of events over plain HTTP. WebSockets open a two-way channel of small frames. WebTransport is a newer option that runs over HTTP/3.
The big idea
With SSE, the server writes events down one HTTP response that never ends. The client sends everything else as ordinary requests. With a WebSocket, a connection starts as an HTTP request and then switches to a binary or text frame protocol, in both directions. The choice comes down to who talks, and how often.
Walking through it
SSE. The response has the content type text/event-stream. Browsers expose it through EventSource:
HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache
id: 1041
event: message
data: {"channel":"general","text":"deploy finished"}
id: 1042
event: typing
data: {"user":"priya"}SSE has real advantages. It is plain HTTP, so it works with existing load balancers, auth and HTTP/2 multiplexing. The browser reconnects automatically, and it sends a Last-Event-ID header on reconnect. The server can then replay what the client missed. Here is a trace:
Connection drops after event 1042.
Browser reconnects with header: Last-Event-ID: 1042
Server replays 1043, 1044, 1045 from its buffer.Warning
Over HTTP/1.1, browsers allow about 6 concurrent connections per domain, and each SSE stream uses one. Open SSE in seven tabs and the seventh hangs. Serve SSE over HTTP/2 or HTTP/3, where streams share one connection.
WebSockets. A connection starts with an HTTP request that includes Upgrade: websocket. The server replies 101 Switching Protocols. After that, the TCP connection carries small frames in both directions, with 2 to 14 bytes of framing overhead. That makes WebSockets the default for chat, multiplayer games, collaborative editing and trading screens.
What you give up is HTTP after the handshake. HTTP caching, standard retries and many middleboxes no longer apply. There is no built-in reconnect, resume, acknowledgement or backpressure. You build those yourself, or use a library such as Socket.IO or a managed service.
WebTransport runs over HTTP/3 and QUIC. It offers several independent streams, so a lost packet on one stream does not stall the others, which TCP cannot avoid. It also offers unreliable datagrams for data where the latest value matters more than every value, such as game state or cursor positions. Major browsers now support it, though server tooling is younger than WebSockets'.
Choosing. Live scores and notifications, where the server pushes and the client rarely sends, start with SSE. Chat and collaborative editing, where the client sends often, need WebSockets. Refresh-every-30-seconds data needs only polling.
Common mistakes
- Using SSE over HTTP/1.1 with many tabs. The connection limit causes hangs.
- Using WebSockets for one-way updates. You take on reconnect and resume work that SSE gives for free.
- Building WebSockets without reconnect logic. Connections drop, and the code must recover.
Check yourself
-
Why does SSE recover from disconnects better than a plain WebSocket?
Answer: browsers reconnect
EventSourceautomatically and sendLast-Event-ID, so the server can replay what was missed. A WebSocket needs your own reconnect and replay code. -
Why serve SSE over HTTP/2?
Answer: HTTP/1.1 allows about six connections per domain, and each SSE stream uses one. HTTP/2 multiplexes streams over one connection.
Key takeaways
- SSE is a one-way stream over HTTP, with automatic reconnect and replay.
- WebSockets give two-way frames, with 2 to 14 bytes of overhead per message.
- WebSockets need you to build reconnect, resume and acknowledgements yourself.
- WebTransport adds independent streams and datagrams over HTTP/3.
Further learning
Hussein Nasser's video covers the WebSocket handshake, framing and trade-offs, with working code:
His Server-Sent Events video compares SSE with WebSockets and long polling:
The MDN references are the authoritative details for both APIs:
MDN: The WebSocket APIThe WebSocket API makes it possible to open a two-way interactive communication session between the user's browser and a server. With this API, you can send messages to a server and receive responses without having to…MDN Web Docs
MDN: Using server-sent eventsDeveloping a web application that uses server-sent events is straightforward. You'll need a bit of code on the server to stream events to the front-end, but the client-side code works almost identically to websockets …MDN Web Docs
Next, see how a server fleet holds these connections, in gateways and connection registry.
Related
Real-time delivery
How a server pushes updates to clients that did not ask, from polling to WebSockets, and the gateway, pub/sub and reconnect design that serves millions of open connections. Start here for the real-time map.
Polling and long polling
How a client gets updates by asking, why short polling wastes almost every request, and how long polling holds each request open until there is news.
Gateways and connection registry
Why real-time servers split into thin stateful gateways and stateless services, how a TTL registry finds the gateway holding a user, and how many connections one machine can hold.
Case study: LLM chat product
Designing a ChatGPT-style product, covering the request path, token streaming, conversation context, GPU capacity math, token-based rate limits, tools and untrusted input, and what to do when capacity runs short.