SSE
Server-Sent Events: a one-way channel where the server pushes updates to the client over HTTP. Simpler than WebSockets when you only need server-to-client streaming.
What is SSE?
In short
Server-Sent Events (SSE) is a web technology where a server keeps one HTTP connection open and streams a continuous flow of text updates to the browser, one event at a time. It is a one-way push channel, server to client only, built on plain HTTP and exposed in browsers through the EventSource API.
What SSE actually is
Server-Sent Events let a server push data to a client whenever it has something new, without the client asking again. The client opens a single HTTP request, the server holds it open, and instead of sending one response and closing, it keeps writing small chunks of text down the same connection.
The browser side is one line of JavaScript: new EventSource('/stream'). That object fires a message event every time the server sends data, plus open and error events. There is no extra protocol to learn and no separate port to manage. It travels over the same HTTP and HTTPS you already use.
The key word is one-way. SSE pushes from server to client only. The client cannot send messages back over the same channel. If the browser needs to talk to the server, it makes a normal separate HTTP request. That limitation is exactly why SSE is simpler than the alternatives.
How it works under the hood
The server responds with the content type text/event-stream and never closes the body. Each event is plain UTF-8 text in a tiny format: a line starting with data: holds the payload, an optional event: line names the event type, an optional id: line tags the event, and a blank line marks the end of one event. The server can also send retry: to tell the client how long to wait before reconnecting.
Reconnection is built in and automatic. If the connection drops, the browser waits a few seconds and reconnects on its own. It also sends the last id it received in a Last-Event-ID header, so a well-written server can resume from where the client left off instead of replaying everything. You get this resilience for free, which is something WebSockets make you build yourself.
One trap to know about: over HTTP/1.1 a browser allows only about 6 connections per domain, and each open SSE stream eats one of those slots across all tabs. HTTP/2 fixes this by multiplexing many streams over one connection, raising the practical limit to around 100. If you serve SSE at scale, run it over HTTP/2.
When to use it and the trade-offs
Reach for SSE when the data flows mostly in one direction: server to client. Live sports scores, stock tickers, a notification feed, a build or deploy log that streams as it runs, or token-by-token output from an AI model are all natural fits. You get streaming with almost no infrastructure beyond a normal HTTP endpoint.
Use WebSockets instead when you need true two-way, low-latency traffic, like a multiplayer game, a collaborative editor where both sides type, or a chat app with typing indicators. WebSockets are full duplex and can carry binary frames; SSE is text only and one direction.
The trade-off to weigh is simplicity versus capability. SSE works through proxies and firewalls that already understand HTTP, supports automatic reconnect with resume, and needs no special server. The costs are: text only, no client-to-server channel, the per-domain connection limit on HTTP/1.1, and no native support in Internet Explorer (a polyfill covers that if you still care).
A concrete real-world example
ChatGPT and most LLM APIs stream their answers using SSE. When you ask a question, the server does not wait to compute the whole reply. It opens an event stream and sends each token as a separate data: event, which is why you see words appear one at a time. The OpenAI streaming API literally ends the stream with a special data: [DONE] line over text/event-stream.
Picture a stock dashboard. The browser runs const es = new EventSource('/prices'); es.onmessage = e => updateUI(JSON.parse(e.data)). The server pushes a small JSON event each time a price changes. No polling, no WebSocket handshake, and if the user's wifi blips, the browser reconnects and the server resumes from the last event id. That is the whole feature.
Where it is used in production
OpenAI ChatGPT API
Streams model output token by token as text/event-stream, ending with a data: [DONE] sentinel.
GitHub
Used SSE to push live updates to web pages such as build and CI status without constant polling.
Mercure / Symfony
An open protocol and hub built on SSE for pushing real-time updates to browsers and mobile apps.
Vercel AI SDK
Defaults to SSE to stream chat completions from the server to React components in the browser.
Frequently asked questions
- What is the difference between SSE and WebSockets?
- SSE is one-way, server to client only, over plain HTTP, text only, with automatic reconnect built in. WebSockets are two-way (full duplex), support binary data, and use their own upgraded protocol, but you have to handle reconnection yourself. Use SSE for push-only feeds and WebSockets when both sides must send messages.
- Can the client send data back over an SSE connection?
- No. The SSE channel is server to client only. When the client needs to send something, it makes a normal separate HTTP request like a POST. If you need a single connection that carries traffic both ways, use WebSockets instead.
- Does SSE reconnect automatically if the connection drops?
- Yes. The browser's EventSource reconnects on its own after a short delay, which the server can tune with a retry: field. If the server tagged events with id: lines, the browser sends a Last-Event-ID header on reconnect so the server can resume from the last delivered event.
- How many SSE connections can a browser hold open?
- Over HTTP/1.1 a browser allows only about 6 connections per domain, shared across all tabs, and each open SSE stream uses one. Over HTTP/2 connections are multiplexed, so the practical limit rises to roughly 100. Serve SSE over HTTP/2 if you expect many concurrent streams.
- What content type does an SSE endpoint use?
- It responds with Content-Type: text/event-stream and keeps the response body open, writing events as plain text. Each event uses fields like data:, event:, and id:, separated by a blank line.
Learn SSE hands-on
This page explains the idea. The full lesson lets you step through the ring as servers join and leave, read the implementation, and check yourself with a quiz. It is one of 760+ lessons in the System Design Masterclass, from your first API call to distributed consensus. Eleven Foundation lessons are free, no signup. Lifetime access is ₹499 in India or $7.99 worldwide, one payment, no subscription.
Related lessons
Lessons that touch on SSE as part of a larger topic.
Server-Sent Events (SSE)
One-way server push over HTTP, real-time updates without the complexity of WebSockets
intermediate · messaging event systems
Asset Pipeline
The build process that transforms source files into optimized, production-ready assets with hashing, minification, and bundling
intermediate · web content delivery
Static Asset Optimization
Managing and optimizing CSS, JavaScript, images, and fonts for fast page loads
intermediate · web content delivery
Content Delivery Network (CDN)
Serve content from edge locations worldwide for sub-50ms response times using Cloudflare, CloudFront, and edge caching
foundation · load balancing proxies
The Full ML Platform: Assembling Every Piece Into One Golden Path
How packaging, serving, pipelines, feature stores, registries, monitoring, and scaling assemble into one self-service internal ML platform
ml-foundation · core
See also
Related glossary terms you might want to look up next.
WebSocket
A protocol for full-duplex communication over a single TCP connection. Unlike HTTP, the server can push data to the client without being asked.
HTTP
The protocol powering the web. A request-response model where clients ask for resources and servers respond. Stateless by design.
Rate Limiting
Controlling how many requests a client can make in a given time window. Protects your API from abuse and ensures fair usage.
GraphQL
A query language for APIs where the client specifies exactly what data it needs. No over-fetching, no under-fetching. One endpoint to rule them all.
gRPC
A high-performance RPC framework by Google using Protocol Buffers and HTTP/2. Much faster than REST for service-to-service communication.
Protocol Buffers
Google's language-neutral, binary serialization format. Smaller and faster than JSON. Defines schemas in .proto files that generate typed code for any language.