What is the Last-Event-ID header?
The Last-Event-ID request header is defined in Section 9.2.4 of the WHATWG HTML Living Standard, as part of Server-Sent Events. When an EventSource reconnects after its connection drops, it sends the last event ID it has seen, so the server can resume the stream from that point instead of from the beginning or from “now”.
The value comes from the stream itself. Each event can carry an id: field, and the browser remembers the most recent one as the event source’s last event ID string. It is not reset by events without an id:, so it stays set until the server sends a new one. An id: field with an empty value clears it, and then no Last-Event-ID is sent on the next reconnection. A value containing a NULL character is ignored.
Last-Event-ID: 42The spec treats the value as essentially any UTF-8 string without NULL, LF or CR; whatwg/html issue #7363 is open to define its value space more precisely. It is listed in the IANA HTTP Field Name registry as permanent, referencing HTML.
API Usage & Best Practices
- Give every event you can replay an
id:. Without ids there is nothing to resume from, and a reconnecting client either misses events or receives duplicates. Use something the server can seek on: a sequence number, a log offset, or an opaque cursor that encodes one. - Keep a replay window and decide what happens outside it. Retain enough history to cover a normal reconnection. If the client asks to resume from an id you no longer have, start from now and tell it so with an application event, rather than silently skipping events it will assume it has.
- Treat it as a cursor, not a credential. The client controls the header. Validate it, bound its length, and authorize the stream on the request’s own credentials, never on the id.
- It only arrives on automatic reconnection. The browser sends it when it reestablishes the connection on its own. Calling
new EventSource()again creates an object whose last event ID is empty. A client that needs to resume after a page reload has to carry the id itself, for example in a query parameter. - Use
retry:and204to control reconnection. Aretry:field sets the reconnection delay in milliseconds. A204 No Contentresponse, or any response that is not200 OKwithtext/event-stream, makes the browser fail the connection and stop reconnecting, which is how a server ends a stream for good. See204 No Content. - Non-browser clients have to do it themselves. The behavior above is specified for
EventSourcein browsers. If you write an SSE client in another language, track the lastid:and sendLast-Event-IDon reconnect, or you lose the resume behavior the protocol is built around. See Streaming APIs.
Examples
A stream where each event carries an id:
HTTP/1.1 200 OKContent-Type: text/event-streamCache-Control: no-store
id: 41event: order.updateddata: {"id":"ord_123","status":"packed"}
id: 42event: order.updateddata: {"id":"ord_123","status":"shipped"}The browser’s automatic reconnection after the connection drops:
GET /v1/orders/ord_123/events HTTP/1.1Host: api.example.comAccept: text/event-streamLast-Event-ID: 42A server ending the stream permanently, so the client stops reconnecting:
HTTP/1.1 204 No Content