typescriptintermediate

Health Check Endpoint with Dependency Checks

Express health check endpoint that verifies database, Redis, and disk connectivity with status reporting.

typescript
import { Router, Request, Response } from 'express';
import { Pool } from 'pg';
import { createClient } from 'redis';

const router = Router();

interface HealthCheck {
  status: 'healthy' | 'degraded' | 'unhealthy';
  uptime: number;
  timestamp: string;
  checks: Record<string, { status: string; latency: number }>;
}

async function checkDatabase(pool: Pool): Promise<{ status: string; latency: number }> {
  const start = Date.now();
  try {
    await pool.query('SELECT 1');
    return { status: 'ok', latency: Date.now() - start };
  } catch {
    return { status: 'error', latency: Date.now() - start };
  }
}

async function checkRedis(url: string): Promise<{ status: string; latency: number }> {
  const start = Date.now();
  try {
    const client = createClient({ url });
    await client.connect();
    await client.ping();
    await client.disconnect();
    return { status: 'ok', latency: Date.now() - start };
  } catch {
    return { status: 'error', latency: Date.now() - start };
  }
}

router.get('/health', async (_req: Request, res: Response) => {
  const pool = new Pool();
  const [db, redis] = await Promise.all([
    checkDatabase(pool),
    checkRedis(process.env.REDIS_URL || 'redis://localhost:6379'),
  ]);

  const checks = { database: db, redis };
  const allOk = Object.values(checks).every((c) => c.status === 'ok');

  const health: HealthCheck = {
    status: allOk ? 'healthy' : 'degraded',
    uptime: process.uptime(),
    timestamp: new Date().toISOString(),
    checks,
  };

  res.status(allOk ? 200 : 503).json(health);
});

export default router;

Use Cases

  • Kubernetes liveness and readiness probes
  • Load balancer health monitoring
  • Uptime monitoring integrations

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.