Updated 25 October 2026 · By the Upcertain team
Why cron failures go unnoticed
- cron itself reports nothing. By default output goes to local mail that nobody reads, or nowhere.
- A job that never starts writes no error. A deleted crontab, a server rebuilt from an old image or a stopped scheduler produces silence.
- Failures inside the job are easy to swallow. A script that ignores a failed command exits 0 and looks fine.
- Containers and serverless move the schedule. Jobs scheduled by Kubernetes, a PaaS or GitHub Actions can be paused or skipped by the platform.
Four ways to monitor scheduled jobs
| Approach | Catches | Misses |
|---|---|---|
| Log or email the output | Errors the job reports | Jobs that never start; output nobody reads |
| Error tracking in the job | Exceptions inside the job | Jobs that never start |
| Check the result (a fresh file, a new row) | Missing results | Needs custom code per job |
| Heartbeat (dead man's switch) | Jobs that do not run or do not finish | Wrong results from a job that succeeds |
Heartbeats are the only approach that catches the commonest failure, the job not running at all, without writing custom checks. Combine them with error tracking for the failures a job can report itself.
How heartbeat monitoring works
The job calls a unique URL when it finishes successfully. The monitor knows how often that should happen. If a call does not arrive within the period plus a grace time, it alerts. In a crontab, it is one extra command after &&:
0 3 * * * /opt/jobs/export.sh && curl -fsS -m 10 --retry 3 https://upcertain.com/api/heartbeat/<token>Snippets for Node.js, Python, PHP, Laravel and GitHub Actions are in the heartbeat setup guide.
Choosing the period and grace
The period is how often the job should run. The grace covers the normal variation in start time and run time; a nightly export that takes 10 to 40 minutes needs roughly 45 minutes of grace. Start generous, then tighten it after a week of real data. The dead man's switch guide has a table of examples.
Make the job honest
- Start shell scripts with
set -euo pipefailso a failed step fails the script. - Send the heartbeat at the end, and only on success.
- Give the job a timeout, so a hung job stops and the missing heartbeat alerts you.
- Keep one heartbeat per job, so the alert names the job that stopped.
In Upcertain
Heartbeat monitors take periods from 30 seconds to 30 days and grace up to a day. Missed heartbeats open incidents and alert the same channels as your website monitors, and the next call resolves them.