Next.js health check monitoring for SaaS
Next.js (App Router on Vercel, Railway, or self-hosted) is the default stack for many indie SaaS products. You need a /api/health Route Handler that external monitors can call without a session cookie — and you need to decide what “healthy” means without leaking secrets or hammering Postgres on every probe.
StillOnline runs HTTP GET checks against that route from outside your host, publishes a status page, and alerts you through the StillOnline Telegram bot, Slack, or email when checks fail.
Quick answer
Next.js Route Handlers can expose app/api/health/route.ts returning 200 + { "status": "ok" } in under two seconds on your production HTTPS hostname. Register that URL in StillOnline — Free includes one project, one URL, checks every five minutes (pricing). Use lightweight liveness by default; add a DB ping only if downtime must mean “database unreachable,” and never expose secrets in the JSON body.
Route Handler template (App Router)
Keep the handler edge-compatible if you deploy to Vercel Edge — or force runtime = 'nodejs' when you need Prisma or native drivers.
// app/api/health/route.ts
import { NextResponse } from "next/server";
export const dynamic = "force-dynamic"; // skip static cache for probes
export async function GET() {
return NextResponse.json({ status: "ok" }, { status: 200 });
}
Optional DB ping (serverless-friendly timeout):
// await db.$queryRaw`SELECT 1` with 1s timeout — only if you accept noisier checks
Full design tradeoffs: health endpoint design.
What not to expose publicly
| Do not return | Why |
|---|---|
| Database URLs or API keys | Security leak on a public route |
| Detailed dependency versions | Attack surface |
| User or revenue counts | Privacy + noise |
| Stack traces on failure | Use generic { "status": "error" } + 503 |
StillOnline only checks status code and response time — but customers and scanners may read /api/health too.
Cache and CDN gotchas
| Problem | Solution |
|---|---|
/api/health cached as static | export const dynamic = "force-dynamic" or revalidate = 0 |
| Middleware redirects unauthenticated users | Exclude /api/health from auth middleware |
| Vercel cold start | Minimal handler; see Vercel guide |
Verify from outside:
curl -sS https://yourdomain.com/api/health
Register in StillOnline
- Sign in.
- New project → product name.
- HTTP check →
/api/health, GET, 200, five-minute interval (Free). - Status page in API docs — health quickstart.
Settings → Connect Telegram → StillOnline bot — Telegram guide.
Related guides
- Health endpoint design
- Uptime monitoring on Vercel
- Supabase backend monitoring
- Public status page guide
FAQ
Should StillOnline monitor / or /api/health on Next.js?
Monitor /api/health (or /health) — not / with marketing redirects. StillOnline follows redirects; root paths often add noise — probe redirects.
Should my Next.js health route ping Postgres or Supabase?
Only if “up” must mean “database reachable.” A liveness-only route reduces false positives during migrations — health endpoint design · Neon/PlanetScale checks.
Does StillOnline work with Next.js on Vercel Edge Runtime?
Yes, if /api/health returns 200 over public HTTPS. Edge handlers cannot use some Node DB drivers — design health accordingly or use a nodejs runtime route for DB ping.