What Are Server-Sent Events? SSE Streaming Explained
February 1, 2024
Server-Sent Events (SSE) is a web standard for streaming one-way updates from a server to a browser over a long-lived HTTP connection. The server sends UTF-8 text with the text/event-stream media type, and browser clients commonly consume it through the EventSource API.
SSE works well for notifications, live dashboards, progress updates, operational logs, and streamed AI responses. Use WebSocket instead when the client and server both need to send frequent messages over the same connection.
How Server-Sent Events Work
sequenceDiagram
participant Client
participant Server
Client->>Server: GET /events
Server-->>Client: Content-Type: text/event-stream
loop While the connection is open
Server-->>Client: event, data, id
end
Note over Client,Server: EventSource reconnects after interruption
The client opens an HTTP request and keeps it open. The server writes events as fields separated by blank lines:
event: deployment id: 42 data: {"status":"complete"}
The main fields are:
data: the event payload; consecutivedatalines are joined;event: an optional event type used by named listeners;id: an event ID that helps the client resume after reconnecting; andretry: a suggested reconnection delay in milliseconds.
In a browser, the client-side code is small:
const stream = new EventSource("/events"); stream.addEventListener("deployment", (event) => { const update = JSON.parse(event.data); console.log(update.status, event.lastEventId); }); stream.onerror = () => { console.log("The stream was interrupted; EventSource will retry."); };
When an id is present, a reconnecting browser sends the last value in the Last-Event-ID header. The server can use it to continue from the next available event. The HTML Living Standard defines the event stream format and EventSource behavior.
SSE vs. WebSocket vs. Polling
| Approach | Direction | Connection model | Best fit |
|---|---|---|---|
| Server-Sent Events | Server to client | Long-lived HTTP response | Notifications, dashboards, progress, AI output |
| WebSocket | Bidirectional | Upgraded persistent connection | Chat, multiplayer interaction, collaborative editing |
| Long polling | Mainly server to client | Repeated HTTP requests | Compatibility when streaming is unavailable |
SSE is often simpler than WebSocket when updates only flow to the client. It uses normal HTTP semantics and includes browser reconnection behavior. Its text-only wire format and one-way direction make it less suitable for binary streams or highly interactive bidirectional applications.
Benefits and Limitations
Benefits
- Native browser API:
EventSourcehandles the connection and reconnection loop. - Incremental delivery: the server can send each update as soon as it is ready.
- Standard HTTP transport: existing authentication, TLS, and observability systems can be reused.
- Resume support: event IDs let an application continue after a dropped connection when the server retains event history.
Limitations
- The browser
EventSourceinterface is one-way; client messages require separate HTTP requests. - The standard stream is UTF-8 text, so binary data must be encoded or delivered another way.
- Long-lived connections consume gateway, proxy, and server resources.
- Intermediary buffering or short idle timeouts can delay events or close a healthy stream.
Proxying SSE Through an API Gateway
An API gateway can authenticate clients, route streams, apply connection limits, and record errors. The streaming path needs different operational settings from a short request-response API:
- Do not buffer the response. Buffering defeats incremental delivery by holding events before forwarding them.
- Use appropriate timeouts. Set an idle timeout that matches the application's heartbeat and reconnect strategy.
- Preserve streaming headers. Forward
Content-Type: text/event-stream, cache-control headers, andLast-Event-IDwhere applicable. - Avoid response caching and compression surprises. Test the complete path, including CDNs and load balancers.
- Limit connections deliberately. Request-rate limits alone do not control the number or duration of open streams.
- Handle deployment draining. Stop accepting new streams, allow existing connections to finish where practical, and ensure clients can reconnect.
API7 Enterprise provides route-level traffic management and a proxy-buffering plugin that can disable response buffering for selected streaming routes.
Common Use Cases
| Use case | Typical event data | Why SSE fits |
|---|---|---|
| Live dashboard | Metrics and status changes | Updates flow primarily from server to browser |
| Notifications | Alerts and activity events | Built-in reconnection reduces client code |
| Long-running job | Progress and completion state | The user sees incremental progress |
| AI response | Generated text or tool status | Tokens or chunks can be displayed as they arrive |
| Deployment log | Ordered log lines and result state | Event IDs can support resume behavior |
FAQ
Is SSE the same as streaming HTTP?
SSE is one specific streaming format over HTTP. Other HTTP streaming formats include newline-delimited JSON and arbitrary chunked responses, but they do not automatically use the browser's EventSource behavior.
Do all browsers support Server-Sent Events?
Modern browsers support EventSource, but you should confirm requirements for embedded webviews or older clients. Non-browser clients can consume the text stream with a normal HTTP library.
Can SSE send custom event types?
Yes. Include an event field in the stream and register a matching listener with addEventListener on the client.
When should I choose WebSocket instead?
Choose WebSocket when both sides need frequent, low-latency messages on the same connection or when the application needs binary frames. Choose SSE when the main requirement is reliable server-to-client updates over HTTP.
Next Steps
For related architecture guidance, read about API rate limiting, webhooks, and AI gateway concepts.