Database connection pool health checks for API-only SaaS
Your app returns 500 under load not because Postgres died — the connection pool is exhausted. External monitors that only hit / miss it until customers do.
StillOnline records HTTP status and latency on the URL you register. A well-designed /health or /ready that acquires a connection and returns 503 when the pool is saturated turns pool pressure into a DOWN signal you can show on a status page.
Quick answer
Use GET /ready (or /health if you accept deploy blips) that runs SELECT 1 or pg_pool.acquire() with a short timeout — return 503 when the pool cannot serve a connection in < 500 ms. Register that HTTPS URL in StillOnline; five-minute probes on Free, two consecutive fails → DOWN. Distinguish pool exhaustion (often load-related, may recover) from DB host down (hard outage) in incident text, not necessarily in HTTP code. Template JSON below; full API patterns in API-only monitoring.
Pool exhaustion vs database down
| Symptom | Typical HTTP | Customer impact | Status page label |
|---|---|---|---|
| Pool timeout under traffic | 503 on /ready | Slow errors, timeouts | Degraded or Major if sustained |
| Postgres unreachable | 503 on /ready | Total API failure | API Outage |
| Migrations running | 503 brief | Read-only or errors | Maintenance if planned |
| Process up, no DB check | 200 on /health | False confidence | Avoid for API-only |
PostgreSQL connection pooling limits are finite — health handlers should fail fast.
JSON response template
{
"status": "ok",
"checks": {
"database": "ok"
}
}
Unhealthy:
{
"status": "error",
"checks": {
"database": "pool_timeout"
}
}
Return 503 with status: error. Keep body small — no connection strings per health design.
Implementation sketch (Node / Prisma)
- Use a dedicated small pool or
prisma.$queryRawwith server-side timeout. - Do not run expensive migrations in health path.
/health= process only;/ready= DB — Kubernetes-style split.
curl -sS -w "\n%{http_code}\n" https://api.yourproduct.com/ready
StillOnline setup
- App → HTTP check →
/readyURL → expect 200. - When pool issues persist, open incident on API component — public status page.
- Pro can monitor
/healthand/readyseparately — Free must pick one URL.
Tune false alarms from cold starts — false positive guide.
Related guides
- Health endpoint design
- API-only SaaS uptime checks
- Supabase backend monitoring
- Neon and PlanetScale DB checks
FAQ
Will pool blips page me every night?
Two fails at 5 min interval ≈ 10 min sustained red. Tune pool size and timeout before shortening interval on Pro.
Does StillOnline read the JSON database field?
No — only HTTP code and timing. Your handler must map pool failure to 503.
Managed DB status page enough?
status.supabase.com and similar show platform outages, not your pool settings — monitor your /ready.