Skip to content
All essays
ArchitectureMarch 27, 20258 min

Server-Sent Events: Simple Real-Time Updates

Master Server-Sent Events (SSE). Build simple, efficient real-time updates from server to client.

Ü
Ümit Uz
Mobile & Full Stack Developer

What are Server-Sent Events?

Server-Sent Events (SSE) enable servers to push data to clients over HTTP. It's a simpler alternative to WebSockets for one-way communication.

typescript
// Client-side
const eventSource = new EventSource('/events');

eventSource.onmessage = (event) => {
  console.log('Received:', event.data);
};

SSE vs WebSockets

typescript
// SSE: Server → Client (one-way)
✓ Simpler API
✓ Automatic reconnection
✓ Built-in HTTP caching
✗ Only server-to-client

// WebSockets: Bidirectional
✓ Full duplex
✓ Lower latency
✗ More complex
✗ Manual reconnection

Server Implementation

Node.js with Express

typescript
import express from 'express';

const app = express();

app.get('/events', (req, res) => {
  // Set SSE headers
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');
  
  // Send initial event
  res.write('data: Connected\n\n');
  
  // Send updates every second
  const interval = setInterval(() => {
    const data = JSON.stringify({
      time: new Date().toISOString(),
      value: Math.random()
    });
    
    res.write(`data: ${data}\n\n`);
  }, 1000);
  
  // Cleanup on client disconnect
  req.on('close', () => {
    clearInterval(interval);
  });
});

app.listen(3000);

Client Implementation

Basic Usage

typescript
const eventSource = new EventSource('/events');

eventSource.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log('Time:', data.time);
  console.log('Value:', data.value);
};

eventSource.onerror = (error) => {
  console.error('SSE error:', error);
  eventSource.close();
};

Event Types

typescript
// Server sends named events
res.write('event: update\n');
res.write('data: {"value": 123}\n\n');

// Client listens to specific event
eventSource.addEventListener('update', (event) => {
  const data = JSON.parse(event.data);
  console.log('Update:', data);
});

Use Cases

Live Notifications

typescript
// Server
app.get('/notifications', (req, res) => {
  res.setHeader('Content-Type', 'text/event-stream');
  
  // Send notifications
  notifications.on('new', (notification) => {
    res.write(`data: ${JSON.stringify(notification)}\n\n`);
  });
});

// Client
const notifications = new EventSource('/notifications');
notifications.onmessage = (event) => {
  showNotification(JSON.parse(event.data));
};

Real-Time Analytics

typescript
// Server
app.get('/analytics', (req, res) => {
  res.setHeader('Content-Type', 'text/event-stream');
  
  analytics.on('metric', (metric) => {
    const data = JSON.stringify({
      type: metric.type,
      value: metric.value,
      timestamp: metric.timestamp
    });
    
    res.write(`data: ${data}\n\n`);
  });
});

Progress Updates

typescript
// Server
app.post('/upload', (req, res) => {
  res.setHeader('Content-Type', 'text/event-stream');
  
  uploadFile(req).on('progress', (percent) => {
    res.write(`data: {"progress": ${percent}}\n\n`);
  });
  
  uploadFile(req).on('complete', () => {
    res.write('event: complete\ndata: {}\n\n');
    res.end();
  });
});

Best Practices

  1. 1Handle reconnection automatically
  2. 2Implement heartbeat mechanism
  3. 3Use appropriate retry intervals
  4. 4Handle connection errors
  5. 5Clean up resources properly

Conclusion

SSE provides simple, efficient server-to-client real-time updates. Use it for notifications, analytics, and progress updates.

Simplify real-time with SSE!

Enjoyed this essay? Share it.

Related essays

Next essay
WebRTC: Real-Time Communication in the Browser