Health Check Endpoint
Problem
Implement health check endpoints that accurately report whether your server and its dependencies are ready to handle traffic. A /healthz endpoint checks that the server is alive, while /readyz verifies that all downstream dependencies (database, cache) are actually reachable.
Background
In production, orchestrators like Kubernetes use health checks to decide whether to route traffic to a pod, restart it, or wait for it to become ready. A naive health check that always returns 200 hides real problems — your server might be "alive" but unable to serve requests because the database is down. Smart health checks catch this and let the system heal automatically.
There are two types: liveness probes (/healthz) confirm the process isn't deadlocked, and readiness probes (/readyz) confirm the server can actually do work.
Requirements
GET /health— basic liveness check, always returns200(used by the harness for startup detection)GET /healthz— liveness probe: returns200if the server process is runningGET /readyz— readiness probe: returns200only if both PostgreSQL and Redis are reachable- When a dependency is down,
/readyzreturns503with details about which dependencies failed - The response body must include a
checksobject showing the status of each dependency - Health checks must complete within 2 seconds (use connection timeouts)
Your Server
- Your server receives
PORT(default3000),DATABASE_URL, andREDIS_URLenvironment variables - PostgreSQL and Redis are provided as sidecars — they are up when your server starts
- The harness may stop a sidecar during testing to verify your health check detects the failure
API Contract
`GET /health`
Basic health check (used by harness for startup detection).
- Status:
200 - Body:
{ "status": "ok" }
`GET /healthz`
Liveness probe — is the process alive?
- Status:
200 - Body:
{ "status": "ok" }
`GET /readyz`
Readiness probe — can the server handle requests?
When all dependencies are healthy:
- Status:
200 - Body:
{
class="text-pass">"status": class="text-pass">"ok",
class="text-pass">"checks": {
class="text-pass">"postgres": { class="text-pass">"status": class="text-pass">"ok" },
class="text-pass">"redis": { class="text-pass">"status": class="text-pass">"ok" }
}
}When one or more dependencies are down:
- Status:
503 - Body:
{
class="text-pass">"status": class="text-pass">"error",
class="text-pass">"checks": {
class="text-pass">"postgres": { class="text-pass">"status": class="text-pass">"ok" },
class="text-pass">"redis": { class="text-pass">"status": class="text-pass">"error", class="text-pass">"message": class="text-pass">"Connection refused" }
}
}Useful APIs
The starter code provides a pool (pg.Pool) and redis (ioredis) client. Here's how to use them:
class=class="text-pass">"text-fg-subtle">// PostgreSQL: get a client from the pool and run a test query
const client = await pool.connect();
try {
await client.query(class="text-pass">'SELECT 1');
class=class="text-pass">"text-fg-subtle">// database is reachable
} catch (err) {
class=class="text-pass">"text-fg-subtle">// database is down
} finally {
client.release(); class=class="text-pass">"text-fg-subtle">// always release the client back to the pool
}
class=class="text-pass">"text-fg-subtle">// Redis: send PING command
await redis.ping() class=class="text-pass">"text-fg-subtle">// returns class="text-pass">'PONG' if healthy, throws if down
class=class="text-pass">"text-fg-subtle">// Run multiple async checks in parallel (doesnclass="text-pass">'t short-circuit on failure)
const results = await Promise.allSettled([checkPostgres(), checkRedis()])
class=class="text-pass">"text-fg-subtle">// results[i].status === 'fulfilledclass="text-pass">' → results[i].value
class=class="text-pass">"text-fg-subtle">// results[i].status === 'rejectedclass="text-pass">' → results[i].reason (no .value!)
class=class="text-pass">"text-fg-subtle">// Set a timeout on a promise
const withTimeout = (promise, ms) =>
Promise.race([promise, new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), ms))])Your solution will be tested against these scenarios plus a hidden set.
- 01GET /healthz returns 200 with {status: 'ok'}
- 02GET /readyz returns 200 with status for both postgres and redis when all dependencies are up
- 03GET /readyz response includes a 'checks' object with postgres and redis status
- 04GET /readyz responds within 2 seconds
Hints
Click each hint to reveal it. Take your time — try before you peek.