nestrs-health workspace member, modeled on
the three-probe shape Kubernetes (and @nestjs/terminus) popularized:
liveness (am I running?), readiness (can I serve traffic?),
startup (have I finished booting?). Each probe is an HTTP endpoint
that returns 200 when its indicators all check out, 503 when any one
fails. Results are cached for 5s with in-flight coalescing so a probe
storm from an orchestrator doesn’t run every check N times in parallel.
Mount the three probes
install_probes mounts three endpoints at the server root, unaffected
by set_global_prefix or URI versioning:
GET /__nestrs/health/live— livenessGET /__nestrs/health/ready— readinessGET /__nestrs/health/startup— startup
ProbeKind::all() (liveness + readiness +
startup), ProbeKind::live_and_ready(), or pass them individually.
Each probe runs only its own indicator set — liveness doesn’t include
the database check, readiness does.
Built-in indicators
DatabaseIndicator— runs the sharednestrs_core::DatabasePingcapability (sqlx / Prisma / Mongo). One line, works across every adapter the framework exposes.HttpIndicator(featurehttp) —GETa URL, must be 2xx, bounded by a timeout. Use for third-party dependencies where a hand-rolled ping isn’t worth maintaining.DiskSpaceIndicator(featuredisk) —statvfsthreshold in bytes. Unix-only; the probe reports the feature as missing on Windows rather than crashing.
Custom indicators
Anything that can be checked asynchronously implementsHealthIndicator:
Broker health for microservices
RedisBrokerHealth issues a PING/PONG round-trip; NatsBrokerHealth
opens a TCP connection. Both are bounded — a stuck broker doesn’t hang
the probe forever. BrokerHealthStub (always up) is the default in
projects that haven’t wired a real broker yet.
How the cache works
Every probe result is cached for 5 seconds. If a probe arrives while a check is in flight, the second caller attaches to the first check rather than starting a parallel one —tokio::sync::OnceCell under the
hood. Net effect:
- A single in-flight check per probe kind, even under burst load.
- After 5s, the next request triggers a fresh check.
- Failures don’t stick — if the database recovers within the TTL
window, the next probe sees
Upimmediately.
When to use what
DatabaseIndicator— almost every readiness probe needs this. One line, real signal.HttpIndicator— sparingly. Each one is an outbound dependency you now own failures for. Better: define a narrow contract, check the in-process client, not the upstream.DiskSpaceIndicator— disk pressure kills writes silently. Cheap to add.- Custom
HealthIndicator— any state you can summarize async: queue depth, replica lag, last successful batch timestamp.
See also
- Concepts: providers — indicators are providers; they participate in DI like any other service.
- Guides: microservices — broker health is usually the readiness probe’s main signal.
@nestjs/terminus— upstream documentation for comparison.