Framework Guide
Node.js API Monitoring
Set up health check endpoints and uptime monitoring for your Node.js application. Works with Express, Fastify, Koa, and native HTTP.
Basic Health Endpoint (Native HTTP)
const http = require('http');
const server = http.createServer((req, res) => {
if (req.url === '/health' && req.method === 'GET') {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
status: 'healthy',
timestamp: new Date().toISOString()
}));
return;
}
// ... your other routes
});
server.listen(3000);
Express Health Endpoint
const express = require('express');
const app = express();
// Simple liveness check
app.get('/health', (req, res) => {
res.json({ status: 'healthy' });
});
// Comprehensive readiness check
app.get('/ready', async (req, res) => {
try {
// Check database
await db.query('SELECT 1');
// Check Redis
await redis.ping();
res.json({
status: 'ready',
checks: {
database: 'ok',
redis: 'ok'
}
});
} catch (error) {
res.status(503).json({
status: 'not ready',
error: error.message
});
}
});
Fastify Health Endpoint
const fastify = require('fastify')();
fastify.get('/health', async (request, reply) => {
return { status: 'healthy' };
});
// With schema validation
fastify.get('/ready', {
schema: {
response: {
200: {
type: 'object',
properties: {
status: { type: 'string' },
uptime: { type: 'number' }
}
}
}
}
}, async (request, reply) => {
return {
status: 'ready',
uptime: process.uptime()
};
});
What to Include in Health Checks
- Database connectivity — Can you query the database?
- Cache connectivity — Is Redis/Memcached reachable?
- Memory usage — process.memoryUsage()
- Uptime — process.uptime()
- Version — Useful for debugging deployments
Complete Example with Dependencies
app.get('/health', async (req, res) => {
const health = {
status: 'healthy',
timestamp: new Date().toISOString(),
uptime: process.uptime(),
memory: process.memoryUsage(),
version: process.env.npm_package_version || '1.0.0',
checks: {}
};
// Check database with timeout
try {
const dbStart = Date.now();
await Promise.race([
db.query('SELECT 1'),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('timeout')), 5000)
)
]);
health.checks.database = {
status: 'ok',
responseTime: Date.now() - dbStart
};
} catch (error) {
health.status = 'unhealthy';
health.checks.database = {
status: 'error',
message: error.message
};
}
const statusCode = health.status === 'healthy' ? 200 : 503;
res.status(statusCode).json(health);
});
Best Practices
- Keep it fast — Health checks should respond in under 500ms
- No auth required — Monitoring services need unauthenticated access
- Add timeouts — Don't let slow dependencies hang the health check
- Log health check traffic separately — Avoid cluttering your logs