Server-Sent Events

Published on:

Most important commands to remember

  • curl -N — display streaming data without curl output buffering.
  • curl -i — include response headers so the stream type is visible.

Commands and flags

Option Meaning
-iN Combine response headers (-i) with unbuffered output (-N).
--max-time 10 End the observation after ten seconds.
-H 'Accept: text/event-stream' Request the SSE media type; quoting keeps the header together.

The header expresses a preference. The response Content-Type determines what the server actually returned.

The concepts that matter

1. SSE keeps an HTTP response open for updates

Server-Sent Events (SSE) sends a stream of updates from server to client over HTTP. A browser’s EventSource API manages this pattern. The server keeps the response open and emits events as they become available.

The stream is one-way. A client can make separate HTTP requests to send commands back, but it does not send application messages upstream inside that same response stream. This differs from WebSocket’s bidirectional channel.

2. Text framing identifies complete events

SSE uses UTF-8 text with media type text/event-stream. Fields such as data:, event:, and id: describe an event. A blank line completes an event; multiple data lines can form one event’s data.

A comment line beginning with a colon can act as a heartbeat without dispatching a user event. Receiving arbitrary chunks of TCP data is not the same as receiving complete SSE events; parsing must respect this framing.

3. Reconnection needs server-supported continuity

EventSource can reconnect after interruption. An event ID lets a client report its last received identifier through Last-Event-ID when reconnecting. A retry: field can suggest a reconnection delay in milliseconds.

The identifier does not itself store history. The server needs retained events or another recovery strategy to resume meaningfully. Duplicates and missed retention windows still need application handling. Reconnecting is not automatically exactly-once event delivery.

4. Buffering and idle policy can delay visible updates

An application may emit an event promptly while a proxy buffers the response or an intermediary closes an idle connection. Flushing and appropriate timeouts matter along the full path.

Curl’s no-buffer option changes its own output buffering; it cannot force the server or proxy to flush. An open connection with no events can be a healthy quiet stream, a buffering problem, or a stalled producer. The interpretation depends on the endpoint’s expected behavior.

One small example

Optional: use the existing local SSE endpoint above. The command only observes a stream; it does not create a producer.

curl -iN --max-time 10 -H 'Accept: text/event-stream' http://127.0.0.1:8080/events

Read the HTTP status and Content-Type before interpreting the following lines. Look for complete events separated by blank lines and distinguish data from comments. An HTML error page is not an SSE event merely because the request asked for that media type.

At ten seconds, curl can exit with a timeout even after displaying valid events; the time limit intentionally ends an otherwise ongoing transfer. Curl displays raw SSE text and does not implement EventSource’s automatic reconnection or event dispatch for you.

No events during this window does not prove failure. If the lab has no listener, connection refusal identifies the missing prerequisite. The command leaves no files or background process.

Keep this idea: SSE streams framed events in an HTTP response; timely display and reliable resumption require more than keeping a connection open.