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. The browser's EventSource reads the stream and reconnects on its own when it drops.
Open in cURL Builder A request with this type is filled in.
Header
Content-Type: text/event-streamAt a glance
- Extensions
- None: it describes a body, not a file
- Kind
- Text
- 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.