Learning note

3 min read

Server Sent Events (SSE) Overview

  • System Design

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?

  1. The client sends an initial GET request to the server requesting a specific content type headers
  2. 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
  1. 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:

  1. id - A unique identifier for the event. The browser tracks this; if a disconnection happens, it sends a Last-Event-ID header back so the server can backfill missed events.

  2. event - A custom string to classify the event type, allowing the client to listen for specific messages.

  3. data - The actual text message payload.

  4. 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();
    });
});