Join the discussion on Telegram
Why this matters
The /health endpoint (backend/src/routes/health.routes.ts) returns a single overall status and uses it for the HTTP code (200 vs 503). It treats the service as degraded whenever indexerLag > 60 seconds — but on a freshly deployed instance, or one where STREAM_CONTRACT_ID is intentionally unset (indexer disabled), the indexer state row is stale or absent and the endpoint reports 503 even though the API itself is perfectly healthy. Container orchestrators (Render/Docker, see render.yaml / docker-compose.yml) use health checks for liveness/readiness, so a perpetually-503 health check can cause restart loops or block traffic for a service that is actually up.
Splitting liveness (process up + DB reachable) from readiness/indexer-lag, or making the indexer-lag contribution conditional on the indexer being enabled, makes the health signal trustworthy.
Acceptance criteria
Files to touch
backend/src/routes/health.routes.ts
backend/tests/ (new or existing health test)
Out of scope
- Prometheus / external monitoring integration.
Join the discussion on Telegram
Why this matters
The
/healthendpoint (backend/src/routes/health.routes.ts) returns a single overall status and uses it for the HTTP code (200 vs 503). It treats the service asdegradedwheneverindexerLag > 60seconds — but on a freshly deployed instance, or one whereSTREAM_CONTRACT_IDis intentionally unset (indexer disabled), the indexer state row is stale or absent and the endpoint reports 503 even though the API itself is perfectly healthy. Container orchestrators (Render/Docker, seerender.yaml/docker-compose.yml) use health checks for liveness/readiness, so a perpetually-503 health check can cause restart loops or block traffic for a service that is actually up.Splitting liveness (process up + DB reachable) from readiness/indexer-lag, or making the indexer-lag contribution conditional on the indexer being enabled, makes the health signal trustworthy.
Acceptance criteria
indexerLagin the body for observability, but only let it force a non-200 status when the indexer is actually enabled (STREAM_CONTRACT_IDset) and lagging./health/livevs/health/readysplit, or document the single-endpoint semantics clearly.Files to touch
backend/src/routes/health.routes.tsbackend/tests/(new or existing health test)Out of scope