Server-Sent Events (SSE)

A one-way stream from server to browser over a normal HTTP connection: the server keeps sending chunks, the page reacts as they land.

stream text as it arriveslike ChatGPT typingsseserver sent eventEventSourcestreaming responseserver push over httptext/event-stream

See it

Live demo coming soon

What it is

Server-Sent Events is one long-lived HTTP response that never finishes. The server sets 'Content-Type: text/event-stream' and keeps writing small 'data:' chunks; the browser reads them as they land through the built-in EventSource API. Traffic flows one way only, server to client, which is exactly the shape of token-by-token LLM output, live progress bars, deploy logs, and price tickers.

Reach for SSE before WebSocket whenever the client has nothing to say back. It is plain HTTP, so it rides through existing auth, CDNs, and load balancers, and EventSource reconnects on its own. It also sends back the ID of the last event it saw, in a 'Last-Event-ID' header. Replay is the half it does not do for you: missed events only come back if your server keeps a buffer of recent ones and knows how to resume from that ID. Sending occasional user actions over a normal POST while the stream runs alongside is a perfectly good architecture.

Gotcha: buffering proxies will eat your stream and deliver everything at the end in one lump, which looks exactly like a broken feature. Disable response buffering (nginx 'proxy_buffering off', or the 'X-Accel-Buffering: no' header), and note that EventSource cannot send custom headers, which is why many apps hand-roll SSE over fetch with a readable stream instead.

Ask AI for it

Stream this response to the browser with Server-Sent Events instead of waiting for the full result. On the server, respond with 'Content-Type: text/event-stream', 'Cache-Control: no-cache', and 'X-Accel-Buffering: no', then write each chunk as a 'data:' line terminated by a blank line, with named events for progress, error, and done, plus a periodic comment line as a heartbeat. On the client, consume it with EventSource (or fetch with a readable stream if custom auth headers are needed), append chunks as they arrive, close the connection on the done event, and show a reconnecting state if the stream drops.

You might have meant

websocketlong pollingpollingasynchronous job patterntimeout

Go deeper