Short definition
Server-Sent Events SSE is a browser API and HTTP-based protocol that allows a server to push real-time updates to a client over a single, persistent connection. Unlike WebSockets, SSE is unidirectional: data flows only from server to client. It is built on standard HTTP and works natively in all modern browsers without additional libraries.
Extended definition
SSE defines a standardized way for servers to stream text-based events to a browser or HTTP client. The client opens a connection using the EventSource interface, and the server responds with a content type of text/event-stream. The connection stays open, and the server writes new event data to the response body as it becomes available.
Each event is a plain-text block containing optional fields: data, event, id, and retry. The data field carries the payload, event names allow the client to route messages to specific handlers, and id supports reconnection logic by letting the server know the last event the client received.
server-sent events SSE is well-suited for scenarios where the server originates all updates: live dashboards, activity feeds, log streaming, real-time notifications, and AI chat interfaces that stream token-by-token responses from a language model. It is a simpler alternative to WebSockets when bidirectional communication is not required.
Because SSE runs over HTTP/1.1 or HTTP/2, it passes through standard infrastructure including proxies, load balancers, and CDNs without special configuration in most cases. Automatic reconnection is built into the EventSource API, which retries the connection after a configurable delay when it is interrupted. This makes SSE resilient by default without custom client-side retry logic.
Deep technical explanation
Server-sent events SSE operates over a standard HTTP response that never closes. The server sets Content-Type to text/event-stream and writes newline-delimited text blocks incrementally. Each event block ends with a blank line, signaling to the client that the event is complete and should be dispatched.
EventSource protocol format
A minimal SSE event looks like: data: hello world followed by two newlines. A full event with all fields uses id, event, data, and retry fields on separate lines. The retry field instructs the client how many milliseconds to wait before reconnecting after a connection drop. The Last-Event-ID header is sent by the browser on reconnect, allowing the server to resume from the correct position in an event stream.
Server implementation requirements
The server must keep the HTTP response open and flush data incrementally. In Node.js, this means calling res.write() for each event and never calling res.end() until the session is terminated. In Python with Flask or FastAPI, response streaming is handled via generator functions. The server must also disable response buffering, which some frameworks and reverse proxies enable by default.
On the infrastructure side, Nginx requires the X-Accel-Buffering: no header or the proxy_buffering off directive to prevent buffering SSE responses at the proxy layer. Without this, events accumulate in the proxy buffer and are delivered in batches rather than in real time.
Connection limits and HTTP/2
Under HTTP/1.1, browsers allow a maximum of six concurrent connections per origin. Each open SSE connection consumes one of those slots, which can become a constraint in applications with multiple SSE streams. HTTP/2 resolves this by multiplexing all streams over a single TCP connection, removing the six-connection limit and making SSE more practical at scale.
Common failure modes
Intermediate proxies or load balancers configured with short read timeouts will terminate long-lived SSE connections before the client or server intend. Servers that do not send periodic keep-alive comments (lines starting with a colon) may also see connections silently dropped by idle-timeout policies. Memory leaks occur when server-side event emitters or listeners are not cleaned up after the client disconnects, which is a common oversight in Node.js implementations.
Practical examples
AI chat token streaming
A product team building an AI assistant needed to stream LLM responses token by token rather than waiting for the full response. They used SSE on a Node.js backend to write each token as a separate data event. The client rendered tokens progressively, reducing perceived latency from several seconds to near-instant feedback.
Live operations dashboard
A DevOps platform needed to push real-time job status updates to an operations dashboard without polling. An SSE endpoint on a Python FastAPI service streamed build and deploy events from an internal queue. Replacing a five-second polling interval with SSE reduced dashboard update lag to under 200 milliseconds.
Security event feed
A security analytics platform needed to surface newly detected threats in a browser console without requiring page refreshes. The backend published threat events to an SSE stream. Analysts received alerts within one second of detection, compared to a 30-second delay with the previous polling approach.
Log streaming for CI pipelines
A CI platform streamed live build logs to a React frontend using SSE. Each log line was a data event. The team avoided WebSockets to keep infrastructure simple, and SSE’s native reconnection handled transient network drops without custom client code.
Why it matters
- SSE eliminates polling overhead, reducing unnecessary HTTP requests and server load in real-time applications.
- Built-in reconnection logic in the EventSource API reduces the amount of custom resilience code teams need to write and maintain.
- SSE runs over standard HTTP, which means it works with existing authentication headers, CORS policies, and reverse proxy configurations without protocol-level changes.
- For unidirectional data flows like notifications, feeds, and AI streaming, SSE is significantly simpler to implement and operate than WebSockets.
- HTTP/2 multiplexing removes the browser connection limit that constrained SSE adoption under HTTP/1.1, making it viable for complex single-page applications.
- SSE integrates directly with standard observability tooling because it generates normal HTTP traffic, making it easier to monitor, trace, and debug than WebSocket connections.