Recipe
Server-Sent Events
Unidirectional real-time streams from server to client over a single HTTP connection.
Overview
SSE delivers a continuous stream of text/event-stream data. The client opens a persistent connection and the server pushes events as they occur — no polling, no WebSocket handshake overhead. Ideal for live dashboards, log tails, and notification feeds.
Server Implementation
export async function GET() {
const stream = new ReadableStream({
start(controller) {
const encoder = new TextEncoder()
const interval = setInterval(() => {
const data = JSON.stringify({ time: Date.now() })
controller.enqueue(encoder.encode(`data: ${data}\n\n`))
}, 1000)
// Cleanup on client disconnect
request.signal.addEventListener('abort', () => clearInterval(interval))
}
})
return new Response(stream, {
headers: {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
}
})
}Client Consumption
const source = new EventSource('/api/events')
source.onmessage = (e) => {
const payload = JSON.parse(e.data)
console.log(payload.time)
}
source.onerror = () => source.close()Edge Notes
- • Vercel Edge Functions support SSE with streaming responses.
- • Keep payloads small — large frames may be buffered.
- • Use event IDs for reliable reconnection and last-event-id tracking.