Background
- Server Sent Events (SSE) is an approach where the clients can get automatic, real time text updates from the server over a single, persistent HTTP connection.
- It’s an alternative to client polling for updates - the client initializes the connection once, and the server streams the data down whenever an event occurs
Key things to remember
- SSE is unidirectional, data flows only from server to client
- SSE only supports UTF-8 text data types only (JSON). It cannot transmit binary data like audio or video
- There is native browser support (WHATWG EventSource Javascript API) thereby requiring no external libs on the frontend.
- Incase if the client-server connection drops, the browser automatically tries to reconnect and uses headers to resume the stream precisely where it left off
Usage
SSE is great for AI Chat Streaming updates (token updates), live dashboards (financial stock tickers, game scores, server monitoring tools), status progress bar (file conversion, video encoding), social media feeds/notifications (new likes, messages, news alerts) etc
How it works?
- The client sends an initial GET request to the server requesting a specific content type headers
- The server responds with an HTTP 200 OK status and keeps the connection open by setting the following headers
- Content-Type: text/event-stream
- Cache-Control: no-cache
- Connection: keep-alive
- The server transmits data blocks separated by pairs of empty newlines (
\n\n)
Server Message Format
The server text blocks use 4 predefined field types:
-
id - A unique identifier for the event. The browser tracks this; if a disconnection happens, it sends a
Last-Event-IDheader back so the server can backfill missed events. -
event - A custom string to classify the event type, allowing the client to listen for specific messages.
-
data - The actual text message payload.
-
retry - An optional value (in milliseconds) telling the browser how long to wait before attempting a reconnection.
Sample Code
Conceptual Client Side Code
Client subscribes to the SSE endpoint and adds event handlers
// Connect to the SSE backend endpoint
const source = new EventSource('/api/live-updates');
// Listen to generic messages (without an "event:" line)
source.onmessage = (event) => {
console.log("Generic message:", event.data);
};
// Listen to specific custom event names
source.addEventListener('pricing', (event) => {
const stock = JSON.parse(event.data);
console.log(`Stock ${stock.ticker} is now $${stock.price}`);
});
// Handle errors or disconnections
source.onerror = (error) => {
console.error("EventSource failed:", error);
};
Conceptual Server Side Code
Server sends headers and an update per set interval
app.get('/api/live-updates', (req, res) => {
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
// Send an update every 3 seconds
const intervalId = setInterval(() => {
res.write(`event: pricing\n`);
res.write(`data: {"ticker": "AAPL", "price": 175.50}\n\n`); // Double newline triggers the event
}, 3000);
req.on('close', () => {
clearInterval(intervalId);
res.end();
});
});