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

Monitor your Node.js API

Add your health endpoint to UptimeSignal and get alerted when it fails.

Start monitoring free →

More Framework Guides