Lesson 0001 · ~8 minutes
One skill: place Server-Sent Events on the realtime spectrum and pick it only when the problem is mostly server → browser push.
After the quiz, you can defend “SSE yes / SSE no” for a feature in a design review without memorizing API trivia.
Normal HTTP is request → response → done. If the server learns something later (order shipped, job 40% done, model token ready), the page does not know unless it asks again or keeps a channel open.
Server-Sent Events (SSE)
are a standard way for the server to keep an HTTP response open and
push text events to the browser whenever it wants. The
browser API is
EventSource. The wire format is defined in the
HTML Living Standard.
Direction is the whole plot:
unidirectional — server → client on that connection.
The client still talks to the server with ordinary
fetch/forms for commands.
Think of these as tools ordered by “how much persistent channel do we need?” — not by coolness.
Timer asks “anything new?” Simple. Wasteful when quiet. Lag equals your interval. Good when updates are rare and slightly stale is fine.
Server holds the request until data (or timeout). Better latency than short poll; still reconnect churn after every payload.
One long-lived HTTP stream of events. Browser reconnects for you. Ideal when many updates flow one way over minutes/hours.
Full-duplex socket after upgrade. Both sides chat freely; binary OK. More protocol/ops surface. Reach for it when you need two-way or binary on the same pipe.
Google’s web.dev SSE guide frames the same comparison: polling and long-polling are the AJAX predecessors; WebSockets win for games/messaging; SSE wins when you only need server push over HTTP and want built-in reconnection and event IDs.
If the hard part is “keep the UI up to date as the server learns things” and the client’s messages are ordinary REST/GraphQL calls, start with SSE (or even polling if traffic is tiny). If the hard part is “both sides stream continuously with low latency” (chat typing, multiplayer, collaborative cursors), start with WebSockets (or a managed realtime product built on them).
| Signal | Leans SSE | Leans away from SSE |
|---|---|---|
| Direction | Server pushes state / tokens / progress | Client must stream continuously on same channel |
| Payload | UTF-8 text (often JSON lines) | Binary frames, custom framing, heavy duplex |
| Infra | Works over plain HTTP(S); same CDNs/auth cookies often OK | Need POST body stream, arbitrary request headers on connect |
| Client cost |
new EventSource(url) + listeners; auto-reconnect
|
You reimplement reconnect, heartbeats, resume yourself |
| Classic fits | Notifications, dashboards, job progress, LLM token streams, live feeds | Multiplayer games, 1:1 chat with continuous duplex, screen share |
Client code is easy — a few lines of
EventSource. What bites teams is not the API: proxies
buffering the stream, idle timeouts, HTTP/1 connection limits (many
tabs to same origin), auth that wants a custom header (native
EventSource can’t set one), and multi-instance backends
that forget to resume with Last-Event-ID. We’ll cover
those in later lessons; today only know they exist so you don’t
oversell “it’s free.”
Choose the best default. Equal-length options so formatting doesn’t hint. Feedback is immediate.
Admin dashboard: warehouse updates order status every few seconds. Operators also click buttons that call REST APIs.
Consumer chat: users send messages, see typing indicators, and get inbound messages with low latency.
AI feature: user submits a prompt once; the model streams tokens to the UI for ~20 seconds.
Marketing site badge: “X people signed up today.” Updates once an hour; slightly stale is fine.
EventSource (reconnect & event IDs built in).
web.dev — Stream updates with server-sent events (Eric Bidelman). Best short primary for this lesson’s comparison framing. Then skim the WHATWG introduction for the normative mental model.