Building a Real-Time Dashboard with Server-Sent Events
WebSockets vs Server-Sent Events
WebSockets are bidirectional — great for chat apps. But most dashboards only need server-to-client updates. That's exactly what Server-Sent Events (SSE) provide, with less complexity.
| Feature | WebSocket | SSE |
|---|---|---|
| Direction | Bidirectional | Server → Client |
| Reconnection | Manual | Automatic |
| Protocol | ws:// | http:// |
| Complexity | High | Low |
Setting Up SSE in Next.js
// app/api/events/route.ts
export async function GET() {const stream = new ReadableStream({
start(controller) {
const interval = setInterval(() => {
const data = JSON.stringify({
visitors: Math.floor(Math.random() * 1000),
timestamp: new Date().toISOString(),
})
controller.enqueue(encoder.encode(data: ${data}\n\n))
}, 1000)
return () => clearInterval(interval) }, })
return new Response(stream, { headers: { "Content-Type": "text/event-stream", "Cache-Control": "no-cache", Connection: "keep-alive", }, }) } ```
Client-Side Consumption
"use client"export function LiveMetrics() { const [data, setData] = useState<MetricData | null>(null)
useEffect(() => { const source = new EventSource("/api/events") source.onmessage = (e) => setData(JSON.parse(e.data)) return () => source.close() }, [])
return <MetricCard value={data?.visitors ?? 0} /> } ```
Tip
EventSource automatically reconnects on network failures — no manual retry logic needed.
Production Considerations
- Use a message broker (Redis pub/sub) for multi-instance deployments
- Set appropriate timeouts to prevent resource leaks
- Implement backpressure for high-frequency updates
editor
Full-stack developer and open-source contributor. Writes about Node.js, databases, and system design. Core maintainer of several popular npm packages.
Comments (1)
SSE is so underrated! We replaced our WebSocket-based notifications with SSE and reduced our server complexity by 60%.
Related Posts
Building a Design System with Tailwind CSS v4 and React
Learn how to create a scalable, token-based design system using Tailwind CSS v4's new CSS-first configuration and React component patterns.
The Complete Guide to Next.js 16 App Router
Everything you need to know about Next.js 16's App Router — from layouts and loading states to parallel routes and intercepting routes.
Mastering TypeScript Generics: Real-World Patterns
Move beyond basic generics with practical patterns for type-safe APIs, component props, and utility types that you'll use every day.