Monitoring & Health Checks

/healthz, /metrics, Pino-Pretty Off in Prod

Monitoring & Health Checks

A health endpoint, JSON Pino logs, and Prometheus metrics cover most observability needs for a Fastify service.

4 min read Level 2/5 #fastify#monitoring#observability
What you'll learn
  • Add a /healthz endpoint returning 200 OK
  • Expose Prometheus metrics with fastify-metrics
  • Pipe Pino logs to an aggregator

You don’t need a heavy observability stack to ship safely — a health endpoint, JSON logs, and a metrics scrape endpoint handle 90% of operational needs.

Health Endpoint

app.get('/healthz', async () => ({ status: 'ok' }));

app.get('/readyz', async () => {
  await app.pg.query('select 1');
  return { status: 'ready' };
});

/healthz is a liveness probe (process is alive). /readyz is a readiness probe (deps are reachable). Kubernetes, Cloud Run, and most load balancers use these.

Prometheus Metrics

import metrics from 'fastify-metrics';

await app.register(metrics, {
  endpoint: '/metrics',
  routeMetrics: { enabled: true },
});

Scrape /metrics from Prometheus, Grafana Cloud, or Datadog Agent. You get request counts, durations by route and status code, event-loop lag, and Node process stats — all for free.

Production Logging

Fastify’s built-in Pino logger is the right call — just turn off pino-pretty in production so logs stay as parseable JSON.

const app = Fastify({
  logger:
    process.env.NODE_ENV === 'production'
      ? { level: 'info' }
      : { level: 'debug', transport: { target: 'pino-pretty' } },
});

Ship JSON to Datadog, Loki, CloudWatch, or whatever you use. Avoid console.log — it bypasses the request context.

Performance Tuning →