Sse Event Stream Format
title: "SSE Event Stream Format" description: "Learn the Server-Sent Events event stream format including data fields, event types, IDs, retry intervals, and protocol rules." weight: 13 date: 2026-06-28 lastmod: 2026-06-28 tags: ["apis", "sse"]
The SSE event stream format defines how data is structured and transmitted from server to client. Understanding the format is essential for building correct SSE implementations.
## What You'll Learn
- SSE event stream structure
- Field types: data, event, id, retry
- Comment lines
- Event boundaries
- UTF-8 encoding requirements
## Why It Matters
Correctly formatted SSE streams ensure reliable parsing on the client side. Format errors cause parsing failures, lost events, or broken connections.
## Real-World Use
A real-time monitoring system sends structured SSE events with fields for event type, metric name, value, and a unique ID for tracking. The client parses each field to update specific dashboard widgets.
## Flow Chart
```mermaid
flowchart LR
A[SSE Stream] --> B[Field: event]
A --> C[Field: data]
A --> D[Field: id]
A --> E[Field: retry]
B --> F[Named Event Type]
C --> G[Payload String]
D --> H[Last Event ID]
E --> I[Reconnection Time]
Code Examples
Example 1: All SSE Field Types
// Server sending different SSE fields
const http = require('http');
http.createServer((req, res) => {
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
});
// Comments start with ':'
res.write(': This is a comment line\n\n');
// Send event with all fields
res.write(
'id: event-001\n' +
'event: user-update\n' +
'data: {"name": "Alice", "status": "online"}\n' +
'\n'
);
// Send another event
res.write(
'id: event-002\n' +
'data: {"message": "Hello World"}\n' +
'\n'
);
// Multi-line data field
res.write(
'id: event-003\n' +
'data: {\n' +
'data: "line1",\n' +
'data: "line2"\n' +
'data: }\n' +
'\n'
);
// Set reconnection time
res.write('retry: 5000\n\n');
// Send without event type
res.write(
'id: event-004\n' +
'data: unnamed event\n' +
'\n'
);
}).listen(3000);
Expected output: Client receives events with different field combinations, including named events, IDs, multi-line data, and retry interval.
Example 2: Client Parsing Different Fields
const source = new EventSource('/events');
// Handle named events
source.addEventListener('user-update', (event) => {
console.log('Event type:', event.type);
console.log('Event ID:', event.lastEventId);
console.log('Data:', event.data);
});
// Handle unnamed events (onmessage)
source.onmessage = (event) => {
console.log('Unnamed event');
console.log('ID:', event.lastEventId);
console.log('Data:', event.data);
};
// Track last event ID for reconnection
let lastEventId = null;
source.onmessage = (event) => {
lastEventId = event.lastEventId || lastEventId;
processEvent(event.data);
};
// The client sends Last-Event-ID header on reconnection
// Server can read it from the request headers
Expected output: Client correctly parses event types, IDs, and data fields, tracking the last event ID for reconnection.
Example 3: Proper Event Stream Generation
function sendSSEEvent(res, options = {}) {
const {
data,
event,
id,
retry,
} = options;
let message = '';
// Event type (optional)
if (event) {
message += `event: ${event}\n`;
}
// Data (required)
if (data) {
// Handle multi-line data
const lines = String(data).split('\n');
lines.forEach(line => {
message += `data: ${line}\n`;
});
}
// Event ID (optional)
if (id) {
message += `id: ${id}\n`;
}
// Retry interval (optional)
if (retry) {
message += `retry: ${retry}\n`;
}
// Empty line terminates the event
message += '\n';
res.write(message);
}
// Usage
sendSSEEvent(res, {
event: 'stock-price',
data: JSON.stringify({
symbol: 'AAPL',
price: 175.50,
change: 2.30,
}),
id: `stock-${Date.now()}`,
});
sendSSEEvent(res, {
data: 'Simple message without type or ID',
});
Expected output: A reusable function that generates properly formatted SSE events with all optional fields.
Common Mistakes
| Mistake | Explanation |
|---|---|
| Missing trailing newlines | Each event must end with \n\n (two newlines) |
| Using wrong field names | Valid fields are event, data, id, and retry only |
| Including colons in field names | Field names must not contain colons; the colon separates field name from value |
| Sending binary data | SSE only supports UTF-8 text; binary must be Base64-encoded |
| Not escaping newlines in data | Data containing newlines must be split across multiple data: lines |
Practice Questions
- What are the four field types in SSE?
- How do you send multi-line data in SSE?
- What is the purpose of the
idfield? - How does the
retryfield affect the client? - What is the purpose of comment lines starting with
:?
Challenge
Build an SSE event generator that creates a properly formatted stream with named events, IDs, and retry intervals. Include multi-line data and comments. Create a test client that validates each event format.
FAQ
Mini Project
Build an SSE stream inspector tool that connects to any SSE endpoint, displays each event with its fields, shows raw stream content, and validates the event format. Include the ability to send test events for debugging.
What's Next
Learn about the EventSource API in browsers
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro