---
concept: SSE Protocol
slug: sse-protocol
verified: true
verification_date: 2026-06-27
sources:
  - url: https://html.spec.whatwg.org/multipage/server-sent-events.html
    title: HTML Living Standard - Server-sent events
    language: en
    date: 2022-03-31
    excerpt: "The event stream format is a text format... Each event consists of a series of lines, separated by U+000A LF characters."
  - url: https://zhuanlan.zhihu.com/p/1903527326400094395
    title: SSE（Server-Sent Events）技术详解
    language: zh
    date: 2025-05-20
    excerpt: "SSE 是 HTML5 标准中定义的一种基于 HTTP 的服务器向客户端单向推送实时数据的协议。"
  - url: https://qiita.com/tenda_ryo_y/items/8cbf19e5c9e0273cf7e3
    title: Server Sent Events（SSE）ではじめるリアルタイム通信
    language: ja
    date: 2025-07-29
    excerpt: "SSEは「サーバーからクライアントへの一方向通信」に特化した技術"
related:
  - eventsource-api
  - sse-vs-websocket
tags:
  - protocol
  - http
  - realtime
---

# SSE Protocol

## Definition
SSE (Server-Sent Events) is an HTTP-based protocol for unidirectional server-to-client streaming. The server holds an HTTP connection open and pushes text events in a specific format.

## Mechanism
1. Client sends a regular HTTP GET request
2. Server responds with `Content-Type: text/event-stream` and keeps the connection open
3. Server pushes events as text in a specific line-based format
4. Client parses the stream using `EventSource` API or manual parsing

## Event Format
Each event is a block of lines terminated by a blank line (`\n\n`):

```
id: 123              # optional: event ID for reconnection tracking
event: update        # optional: event type (default: "message")
data: Hello World    # required: payload (can have multiple data: lines)
retry: 5000          # optional: reconnection interval in ms
```

A line starting with `:` is a comment (ignored by EventSource, used for heartbeats).

## Response Headers (Required)
```
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
```

The `X-Accel-Buffering: no` header is added when behind Nginx/Caddy to disable proxy buffering.

## Key Details
- Text-only protocol (binary data must be base64-encoded)
- HTTP/1.1 limits to ~6 concurrent connections per domain (HTTP/2 removes this limit)
- Browser's EventSource API handles automatic reconnection
- Server can control reconnection interval via `retry:` field

## Common Misconceptions
- SSE is not bidirectional — client cannot send data back on the same connection
- SSE is not WebSocket — it's simpler, HTTP-based, and unidirectional
- The `data:` field can span multiple lines — each line must start with `data:`

## Application in Blog Project
The blog's pixel-art feature (`/pixel-art/paint`) uses SSE to stream LLM painting steps to the browser in real-time. The server uses `ReadableStream` + `TextEncoder` to write SSE-formatted chunks, and the client uses `fetch` + `ReadableStream.getReader()` to parse them manually (not EventSource API).
