Socket.io powers real-time features in chat apps, collaborative tools, live dashboards, and multiplayer games. Unlike traditional HTTP APIs, Socket.io connections are persistent—which makes monitoring them uniquely challenging. When your Socket.io server goes down, connections don't cleanly fail; they silently hang or throw confusing client-side errors.
This guide shows you how to monitor Socket.io applications with Vigilmon using HTTP health checks alongside your real-time infrastructure.
What Can Go Wrong with Socket.io?
Socket.io failures come in several forms:
- Server crash: The Node.js process dies; all connections drop immediately
- Memory leak: Server accumulates connections without releasing them; eventually OOMs
- Event loop blocking: Heavy computation blocks the event loop; connections queue up or time out
- Adapter failures: Redis adapter for Socket.io in cluster mode loses sync
- Nginx proxy issues: WebSocket upgrade headers misconfigured; connections fall back to polling
- Sticky sessions breaking: Load balancer routes WebSocket to wrong server in cluster
External monitoring catches the most critical failures: server crashes and connectivity issues.
The Core Monitoring Strategy
Since Vigilmon uses HTTP checks (not WebSocket), the strategy is:
- Add HTTP health endpoints to your Socket.io server
- Monitor the HTTP endpoints with Vigilmon
- Expose Socket.io metrics in the health response
This way, if your server is down or unhealthy, Vigilmon catches it within 60 seconds.
Adding Health Endpoints to a Socket.io Server
Express + Socket.io Setup
const express = require('express');
const http = require('http');
const { Server } = require('socket.io');
const app = express();
const server = http.createServer(app);
const io = new Server(server, {
cors: { origin: '*' }
});
// Track connection state
let connectionCount = 0;
let totalConnectionsServed = 0;
io.on('connection', (socket) => {
connectionCount++;
totalConnectionsServed++;
socket.on('disconnect', () => {
connectionCount--;
});
});
// Health check endpoint
app.get('/health', (req, res) => {
const memUsage = process.memoryUsage();
res.json({
status: 'healthy',
uptime: process.uptime(),
activeConnections: connectionCount,
totalServed: totalConnectionsServed,
memory: {
heapUsed: Math.round(memUsage.heapUsed / 1024 / 1024) + 'MB',
heapTotal: Math.round(memUsage.heapTotal / 1024 / 1024) + 'MB',
},
timestamp: new Date().toISOString(),
});
});
// Readiness check (is the server ready to accept connections?)
app.get('/ready', (req, res) => {
// Check if Socket.io is initialized
if (!io) {
return res.status(503).json({ status: 'not ready' });
}
res.json({ status: 'ready' });
});
server.listen(3000);
Checking Socket.io Engine Health
For more detailed Socket.io metrics:
app.get('/health/detailed', (req, res) => {
const engine = io.engine;
res.json({
status: 'healthy',
socketio: {
activeConnections: connectionCount,
engineConnections: engine ? engine.clientsCount : 0,
pollingConnections: engine ?
Object.values(engine.clients).filter(c => c.transport.name === 'polling').length : 0,
websocketConnections: engine ?
Object.values(engine.clients).filter(c => c.transport.name === 'websocket').length : 0,
},
server: {
uptime: Math.round(process.uptime()),
memoryMB: Math.round(process.memoryUsage().heapUsed / 1024 / 1024),
nodeVersion: process.version,
},
timestamp: new Date().toISOString(),
});
});
Adding Connection Alerts
Set up automatic alerts if connection count drops unexpectedly:
// Alert if connections drop from a high baseline
let maxConnectionsSeen = 0;
const CONNECTION_DROP_THRESHOLD = 0.5; // Alert if 50% drop in 5 minutes
setInterval(() => {
if (connectionCount > maxConnectionsSeen) {
maxConnectionsSeen = connectionCount;
}
if (maxConnectionsSeen > 10 && connectionCount < maxConnectionsSeen * CONNECTION_DROP_THRESHOLD) {
console.error(`ALERT: Connection drop detected. Was ${maxConnectionsSeen}, now ${connectionCount}`);
// Send alert via your preferred method (Slack, PagerDuty, etc.)
}
}, 5 * 60 * 1000);
Monitoring Socket.io in Clusters (with Redis Adapter)
If you run Socket.io in a cluster with the Redis adapter, your health check should verify Redis connectivity:
const { createAdapter } = require('@socket.io/redis-adapter');
const { createClient } = require('redis');
const pubClient = createClient({ url: process.env.REDIS_URL });
const subClient = pubClient.duplicate();
let redisConnected = false;
pubClient.on('connect', () => { redisConnected = true; });
pubClient.on('error', () => { redisConnected = false; });
await Promise.all([pubClient.connect(), subClient.connect()]);
io.adapter(createAdapter(pubClient, subClient));
// Updated health check
app.get('/health', (req, res) => {
if (!redisConnected) {
return res.status(503).json({
status: 'degraded',
reason: 'Redis adapter disconnected',
activeConnections: connectionCount,
});
}
res.json({
status: 'healthy',
activeConnections: connectionCount,
redis: 'connected',
timestamp: new Date().toISOString(),
});
});
Setting Up Vigilmon for Socket.io
- Sign up at vigilmon.online — free, no credit card
-
Create Monitor 1: Health Endpoint
- URL:
https://your-socketio-server.com/health - Method: GET
- Expected status: 200
- Keyword:
"healthy" - Interval: 1 minute
- URL:
-
Create Monitor 2: Server Reachability
- URL:
https://your-socketio-server.com/ - Method: GET
- Expected status: 200 (or 404, if / returns 404 intentionally)
- This checks basic server connectivity
- URL:
-
Create Monitor 3: WebSocket Upgrade Path (if you have a landing page)
- URL:
https://your-app.com/socket.io/ - Method: GET
- URL:
Nginx Configuration for Socket.io (Required for Monitoring)
If you use Nginx in front of Socket.io, ensure it passes health check requests properly:
upstream socketio_backend {
ip_hash; # Required for sticky sessions
server 127.0.0.1:3000;
server 127.0.0.1:3001;
}
server {
listen 443 ssl;
server_name your-app.com;
# WebSocket support
location /socket.io/ {
proxy_pass http://socketio_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
# Health check endpoint (no WebSocket needed)
location /health {
proxy_pass http://socketio_backend;
proxy_set_header Host $host;
# No WebSocket headers needed here
}
}
What to Monitor vs What to Accept
| Issue | Detectable by Vigilmon? | Action |
|---|---|---|
| Server crash | ✅ Yes | Immediate alert |
| High latency | ✅ Yes (response time) | Warning threshold |
| Memory leak | ✅ Partially (via health endpoint) | Alert when heapUsed > threshold |
| Individual socket disconnect | ❌ No | Implement client-side retry |
| Redis adapter failure | ✅ Yes (via health endpoint) | Critical alert |
| WebSocket upgrade failure | ⚠️ Partial | Monitor polling fallback rate |
Sample Alert Configuration
For a production Socket.io application:
Monitor: Socket.io Health
URL: https://api.yourapp.com/health
Interval: 1 minute
Alert after: 2 consecutive failures
Alert channels:
- Email: oncall@yourcompany.com
- Slack: #engineering-alerts
- PagerDuty: Production (for P1 incidents)
Get Started Free
Vigilmon gives you free uptime monitoring with:
- HTTP health checks with keyword validation
- Multi-region monitoring (US, EU, Asia)
- 1-minute check intervals
- Slack, email, and PagerDuty alerts
- Public status page for your users
Get alerted when your Socket.io server goes down — before your users notice dropped connections.
Top comments (0)