Real-time updates make applications feel alive. Users expect to see new data without refreshing pages. Server-Sent Events provide a simple way to achieve this without the complexity of WebSockets.
Understanding Server-Sent Events
Server-Sent Events (SSE) is a technology that enables servers to push data to clients automatically. Unlike traditional HTTP requests where the client initiates everything, SSE allows servers to send updates as they happen.
The client opens a persistent connection to the server. This connection stays open while the client needs updates. When new data arrives, the server sends it immediately through this connection.
SSE uses standard HTTP protocol. This means it works through proxies and firewalls without special configuration. You don't need to switch to WebSockets just to receive updates.
The event stream format is straightforward. Each message starts with "data:" followed by your content. A blank line separates messages. Clients parse this easily with built-in EventSource API.
When to Choose SSE
SSE works well in specific scenarios. Understanding these helps you choose the right technology.
Unidirectional updates suit SSE perfectly. If only the server sends data and the client only receives, SSE provides the simplest solution. Live feeds, news updates, and notification systems work great with SSE.
AI streaming responses are a perfect match. When AI models generate text token by token, SSE delivers each chunk as it completes. Users see responses appear in real-time rather than waiting for the complete answer.
Monitoring dashboards benefit from SSE. Display live metrics, system status, or progress updates without constant polling. The server pushes new numbers as soon as they change.
Simple real-time needs don't require WebSocket complexity. If you only need server-to-client communication, SSE offers a lighter solution with less overhead.
Limitations to Consider
SSE isn't right for every situation. Know the limitations before choosing it.
Server-to-client only is the biggest limitation. If you need the client to send messages to the server in real-time, use WebSockets or another bidirectional protocol.
Browser limits restrict concurrent connections. Most browsers limit SSE connections to six per domain. Plan accordingly for applications with multiple dashboards.
HTTP/2 considerations matter for high-traffic applications. Some servers limit streams under HTTP/2. Test your specific setup if performance is critical.
Setting Up Server-Sent Events
Let's see how SSE works in practice. The Pet Store API supports SSE for real-time updates.
First, the client opens an EventSource connection:
const response = await fetch('https://api.petstoreapi.com/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: 'petstore-ai',
messages: [{ role: 'user', content: 'List available pets' }],
stream: true
})
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value);
console.log('Received:', chunk);
}
The EventSource API is built into browsers. No external libraries required.
Then, listen for specific events:
eventSource.addEventListener('pet-update', (event) => {
const data = JSON.parse(event.data);
console.log('Pet updated:', data);
});
The server sends events with a specific type. Clients can listen to all events or filter for specific ones.
Handle connection events:
eventSource.onopen = () => {
console.log('Connected to event stream');
};
eventSource.onerror = (error) => {
console.error('Connection error:', error);
};
The browser automatically attempts reconnection when the connection drops. This built-in resilience simplifies error handling.
Server Implementation
On the server side, set the correct content type and headers:
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
Each message follows a simple format:
event: pet-update
data: {"id": 5, "status": "sold", "timestamp": 1234567890}
The "event:" line names the event type. The "data:" line contains your payload. The blank line terminates the message.
You can send messages whenever appropriate. The Pet Store API sends updates when pet statuses change. Your application displays these updates instantly.
Practical Example
Imagine building a pet store dashboard. You want to show live updates when pets are added or status changes.
Create an SSE endpoint to stream these changes:
// Server-side pseudocode
app.get('/api/events/pets', (req, res) => {
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
// Send initial data
const pets = getAllPets();
res.write(`data: ${JSON.stringify({ type: 'initial', pets })}\n\n`);
// Subscribe to updates
subscribeToPetUpdates((update) => {
res.write(`data: ${JSON.stringify(update)}\n\n`);
});
});
The client connects once and receives all updates automatically. No polling, no repeated requests, just live data.
SSE vs WebSocket: Making the Choice
Both technologies enable real-time communication. The choice depends on your specific needs.
Choose SSE when:
- You only need server-to-client updates
- You want simple implementation
- You need reliable reconnection
- You're working with AI streaming responses
Choose WebSocket when:
- You need bidirectional communication
- You need low latency messaging
- You need to handle thousands of concurrent connections
- You need custom protocols for specific use cases
Many applications use both. They might use REST for standard operations, SSE for updates, and WebSockets for interactive features like chat.
Pet Store API Implementation
The Pet Store API provides SSE endpoints for real-time pet updates. This simplifies building applications that need live data.
Connect to the event stream at the endpoint. Listen for events that matter to your application. Update your UI automatically when data changes.
The documentation at docs.petstoreapi.com shows available event types. Each event includes the relevant data payload. Handle events to keep your application in sync with the server.
SSE provides an excellent middle ground between polling and WebSockets. It delivers real-time updates with minimal complexity. For many applications, SSE is the perfect solution.