lede: SSE est le pattern défaut pour streaming réponses LLM en 2026. Plus simple que WebSocket, idéal token-by-token.
lede_en: SSE is the default pattern for streaming LLM responses in 2026. Simpler than WebSocket, ideal token-by-token.
title_en: Server-Sent Events for LLM streaming
Pourquoi SSE pour LLM
Streaming LLM responses (token-by-token) améliore l'UX énormément. User voit la réponse arriver en temps réel plutôt que d'attendre 5s.
Options techniques :
- WebSocket : bidirectionnel, mais overhead inutile pour streaming server→client.
- SSE (Server-Sent Events) : unidirectionnel server→client, HTTP/2 natif.
SSE est le bon outil pour streaming LLM.
Implémentation côté serveur
// Hono / Express
app.post('/chat', async (c) => {
return c.streamSSE(async (stream) => {
const llmStream = await anthropic.messages.stream({
model: 'claude-sonnet-4-6',
messages: [...],
max_tokens: 1024,
});
for await (const event of llmStream) {
if (event.type === 'content_block_delta') {
await stream.writeSSE({ data: event.delta.text });
}
}
});
});
OpenAI/Anthropic/Gemini SDK exposent tous des streams. Vous relayez vers SSE.
Côté client
const response = await fetch('/chat', {
method: 'POST',
body: JSON.stringify({ message: 'Hello' }),
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { value, done } = await reader.read();
if (done) break;
const chunk = decoder.decode(value);
// Parse SSE format: "data: <token>
"
for (const line of chunk.split('
')) {
if (line.startsWith('data: ')) {
const token = line.slice(6);
appendToUI(token);
}
}
}
Plus simple qu'EventSource pour POST (EventSource ne supporte que GET).
Vs WebSocket
|
SSE |
WebSocket |
| Direction |
Server → Client |
Bidirectionnel |
| Protocole |
HTTP normal |
WS protocol |
| Reconnect |
Auto |
Manuel |
| Proxies |
Compatible |
Parfois bloqués |
| Use case |
Streaming |
Chat collab |
Pour LLM streaming : SSE clairement.
Patterns avancés
Cancellation :
const controller = new AbortController();
fetch('/chat', { signal: controller.signal });
// User clicks stop
controller.abort();
Côté serveur, détecter abort et stopper LLM stream :
c.req.raw.signal.addEventListener('abort', () => {
llmStream.controller.abort();
});
Économise tokens.
Heartbeat :
// Ping every 15s pour keep-alive
setInterval(() => stream.writeSSE({ event: 'ping' }), 15000);
Évite proxy timeouts.
Limites
- Pas pour bidirectionnel : si user doit envoyer pendant que LLM stream, WebSocket mieux.
- HTTP/1.1 limit : 6 connections par domain. Use HTTP/2 ou multiplex.
Verdict
Pour streaming LLM responses : SSE est standard 2026. Plus simple qu'WebSocket, suffisant pour 95 % des cas.
Why SSE for LLM
Streaming LLM responses (token-by-token) hugely improves UX. User sees response arriving in real time instead of waiting 5s.
Technical options:
- WebSocket: bidirectional, but unnecessary overhead for server→client streaming.
- SSE (Server-Sent Events): unidirectional server→client, native HTTP/2.
SSE is the right tool for LLM streaming.
Server-side implementation
// Hono / Express
app.post('/chat', async (c) => {
return c.streamSSE(async (stream) => {
const llmStream = await anthropic.messages.stream({
model: 'claude-sonnet-4-6',
messages: [...],
max_tokens: 1024,
});
for await (const event of llmStream) {
if (event.type === 'content_block_delta') {
await stream.writeSSE({ data: event.delta.text });
}
}
});
});
OpenAI/Anthropic/Gemini SDKs all expose streams. You relay to SSE.
Client-side
const response = await fetch('/chat', {
method: 'POST',
body: JSON.stringify({ message: 'Hello' }),
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { value, done } = await reader.read();
if (done) break;
const chunk = decoder.decode(value);
// Parse SSE format: "data: <token>
"
for (const line of chunk.split('
')) {
if (line.startsWith('data: ')) {
const token = line.slice(6);
appendToUI(token);
}
}
}
Simpler than EventSource for POST (EventSource only supports GET).
vs WebSocket
|
SSE |
WebSocket |
| Direction |
Server → Client |
Bidirectional |
| Protocol |
Normal HTTP |
WS protocol |
| Reconnect |
Auto |
Manual |
| Proxies |
Compatible |
Sometimes blocked |
| Use case |
Streaming |
Collab chat |
For LLM streaming: SSE clearly.
Advanced patterns
Cancellation:
const controller = new AbortController();
fetch('/chat', { signal: controller.signal });
// User clicks stop
controller.abort();
Server-side, detect abort and stop LLM stream:
c.req.raw.signal.addEventListener('abort', () => {
llmStream.controller.abort();
});
Saves tokens.
Heartbeat:
// Ping every 15s for keep-alive
setInterval(() => stream.writeSSE({ event: 'ping' }), 15000);
Avoids proxy timeouts.
Limits
- Not for bidirectional: if user must send while LLM streams, WebSocket better.
- HTTP/1.1 limit: 6 connections per domain. Use HTTP/2 or multiplex.
Verdict
For streaming LLM responses: SSE is 2026 standard. Simpler than WebSocket, enough for 95% of cases.
lede: SSE est le pattern défaut pour streaming réponses LLM en 2026. Plus simple que WebSocket, idéal token-by-token.
lede_en: SSE is the default pattern for streaming LLM responses in 2026. Simpler than WebSocket, ideal token-by-token.
title_en: Server-Sent Events for LLM streaming
Pourquoi SSE pour LLM
Streaming LLM responses (token-by-token) améliore l'UX énormément. User voit la réponse arriver en temps réel plutôt que d'attendre 5s.
Options techniques :
SSE est le bon outil pour streaming LLM.
Implémentation côté serveur
OpenAI/Anthropic/Gemini SDK exposent tous des streams. Vous relayez vers SSE.
Côté client
Plus simple qu'EventSource pour POST (EventSource ne supporte que GET).
Vs WebSocket
Pour LLM streaming : SSE clairement.
Patterns avancés
Cancellation :
Côté serveur, détecter abort et stopper LLM stream :
Économise tokens.
Heartbeat :
Évite proxy timeouts.
Limites
Verdict
Pour streaming LLM responses : SSE est standard 2026. Plus simple qu'WebSocket, suffisant pour 95 % des cas.
Why SSE for LLM
Streaming LLM responses (token-by-token) hugely improves UX. User sees response arriving in real time instead of waiting 5s.
Technical options:
SSE is the right tool for LLM streaming.
Server-side implementation
OpenAI/Anthropic/Gemini SDKs all expose streams. You relay to SSE.
Client-side
Simpler than EventSource for POST (EventSource only supports GET).
vs WebSocket
For LLM streaming: SSE clearly.
Advanced patterns
Cancellation:
Server-side, detect abort and stop LLM stream:
Saves tokens.
Heartbeat:
Avoids proxy timeouts.
Limits
Verdict
For streaming LLM responses: SSE is 2026 standard. Simpler than WebSocket, enough for 95% of cases.