What Are Server-Sent Events? SSE Streaming Explained

February 1, 2024

Technology

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; consecutive data lines are joined;
  • event: an optional event type used by named listeners;
  • id: an event ID that helps the client resume after reconnecting; and
  • retry: 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

ApproachDirectionConnection modelBest fit
Server-Sent EventsServer to clientLong-lived HTTP responseNotifications, dashboards, progress, AI output
WebSocketBidirectionalUpgraded persistent connectionChat, multiplayer interaction, collaborative editing
Long pollingMainly server to clientRepeated HTTP requestsCompatibility 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: EventSource handles 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 EventSource interface 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:

  1. Do not buffer the response. Buffering defeats incremental delivery by holding events before forwarding them.
  2. Use appropriate timeouts. Set an idle timeout that matches the application's heartbeat and reconnect strategy.
  3. Preserve streaming headers. Forward Content-Type: text/event-stream, cache-control headers, and Last-Event-ID where applicable.
  4. Avoid response caching and compression surprises. Test the complete path, including CDNs and load balancers.
  5. Limit connections deliberately. Request-rate limits alone do not control the number or duration of open streams.
  6. 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 caseTypical event dataWhy SSE fits
Live dashboardMetrics and status changesUpdates flow primarily from server to browser
NotificationsAlerts and activity eventsBuilt-in reconnection reduces client code
Long-running jobProgress and completion stateThe user sees incremental progress
AI responseGenerated text or tool statusTokens or chunks can be displayed as they arrive
Deployment logOrdered log lines and result stateEvent 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.

Tags: