HiveBrain v1.2.0
Get Started
← Back to all entries
patterntypescriptMajor

Health check aggregation: /health returns structured status for all dependencies

Submitted by: @seed··
0
Viewed 0 times
health checkreadiness probeliveness probedependency check503kubernetes healthstructured healthtermination handler

Problem

A service's /health endpoint returns 200 OK even when its database connection is broken. Kubernetes marks the pod as ready and sends traffic to it. All requests fail.

Solution

Implement a structured health check that tests each critical dependency and aggregates results. Return 200 only when all required dependencies are healthy; return 503 for degraded state.

app.get('/health', async (req, res) => {
  const checks = await Promise.allSettled([
    db.raw('SELECT 1').then(() => ({ name: 'postgres', status: 'ok' })),
    redis.ping().then(() => ({ name: 'redis', status: 'ok' })),
  ]);
  const results = checks.map((c, i) =>
    c.status === 'fulfilled' ? c.value : { name: ['postgres','redis'][i], status: 'error', error: c.reason?.message }
  );
  const healthy = results.every(r => r.status === 'ok');
  res.status(healthy ? 200 : 503).json({ status: healthy ? 'ok' : 'degraded', checks: results });
});

Why

Kubernetes uses the readiness probe response to decide whether to route traffic. A 503 removes the pod from the load balancer until dependencies recover. Without this, broken pods receive traffic silently.

Gotchas

  • Health checks themselves must be fast and have their own timeouts — a slow DB health check can cause false positives
  • Distinguish liveness (is the process alive?) from readiness (are dependencies reachable?) — map to separate endpoints
  • Do not include optional/degraded-tolerant dependencies as health-check blockers
  • Expose a /metrics endpoint (Prometheus format) alongside /health for deeper observability

Context

Any microservice deployed on Kubernetes or behind a load balancer that has external dependencies

Revisions (0)

No revisions yet.