text/event-stream
A text/event-stream response stays open, and the server writes events into it as they happen: lines starting with data:, each event ended by a blank line.1 The browser's EventSource reads the stream and reconnects on its own when it drops.
- Kind text
- Extensions none
Open in cURL Builder A request with this type is filled in.
Header
Content-Type: text/event-streamAt a glance
- Parameters
- None
- In a browser
- Read with
new EventSource(url), which fires amessageevent for each event without anevent:field, and an event of that name for the others.
With curl
curl -N -H 'Accept: text/event-stream' https://api.example.com/events
With fetch
const res = await fetch('https://api.example.com/events', { headers: { Accept: 'text/event-stream' } });
const reader = res.body.pipeThrough(new TextDecoderStream()).getReader();
for (;;) {
const { value, done } = await reader.read();
if (done) break;
console.log(value);
}Common mistakes
Proxies that buffer
nginx buffers proxied responses by default and holds events back until a buffer fills. Send
X-Accel-Buffering: nofrom the app, or setproxy_buffering offfor that location.Compression holds events too
A gzip layer that waits for a full block delays small events. Leave event streams uncompressed, or flush after every event.
Connection limits on HTTP/1.1
Browsers open about six connections per host over HTTP/1.1, and each open
EventSourcekeeps one busy. Over HTTP/2 the streams share one connection.
Sources
- 1 HTML Standard, Server-sent events. html.spec.whatwg.org ↩︎