Scheduling health checks with cron
Cron's one-minute floor is too coarse for most health checks — here's what to use instead, and when cron is fine.
The problem
Cron's finest granularity is once per minute. For an externally-facing service, a one-minute-or-slower check means up to a minute of undetected downtime before anything even starts noticing, and cron itself has no retry, backoff, or alerting — it just runs a script; turning a failed check into a page is entirely on you to build.
Purpose-built monitoring (uptime checkers, Healthchecks-style dead-man's-switches, or norc's own run-history view for scheduled jobs) already does sub-minute polling, retries, and alert routing. Reaching for cron here usually means rebuilding a worse version of a tool that already exists.
Use a real monitoring tool for anything user-facing; reserve cron for internal, low-urgency checks.
If a check needs to fire faster than once a minute, or needs retries/backoff/on-call paging when it fails, that's a monitoring product's job, not cron's. A cron-based check script is fine for low-urgency internal signals — "did this batch job leave a lock file behind," "is this internal service still listening" — where a delay of a few minutes before anyone notices is acceptable.
Recommended schedule
*/5 * * * *
Every 5 minutes is a reasonable floor for a low-urgency internal check. Anything more time-sensitive than that belongs in dedicated monitoring rather than cron.
Check any expression at the cron parser, or browse more at the cron guide.
Example crontab entry
# norc: healthcheck-internal Check internal queue worker is listening
*/5 * * * * /usr/bin/curl -sf --max-time 5 http://127.0.0.1:9200/healthz || /opt/scripts/alert.sh "worker down" Failure modes to watch for
- No --max-time on the check request: a hung endpoint makes the check itself hang, delaying the next scheduled run instead of failing fast.
- Alerting only on a single failed check with no debounce, paging on a single dropped packet instead of a real outage.
- The alert script itself has a single point of failure (one SMTP relay, one webhook) with no fallback, so the exact outage that should trigger an alert also takes down the alerting path.
- Checking the process is running (`pgrep`) instead of that it's actually serving traffic — a hung-but-alive process passes a liveness check while failing every real request.
How norc helps
For scheduled jobs specifically (not general uptime monitoring), norc already tracks whether each run happened and what it returned — often enough signal on its own without a separate check script.