heartbeat checks
Find out when a scheduled job stops running
A cron job that stops running produces no error and leaves nothing to poll, because the thing you want to check is a job that is not there. A heartbeat reverses the direction: your job calls a URL we give it, and we tell you when the calls stop.
The failure nothing reports
A job that fails loudly is the easy case. It exits nonzero, something catches it, someone gets paged. The costly case is the job that stops being run at all, because a crontab was edited away or the container holding it no longer starts. There is no process left to fail, so nothing is reported, and the dashboard stays as green as it was while the job still worked. GitLab found their nightly backup that way, months late.
A period and a grace, set to what the job really does
You say how often you expect the ping and how late it may be before it counts as failed. A job that runs hourly with a ten-minute grace flips to failing ten minutes after the missed run, and the alert follows once the confirmation count is met. Set the period to how often the job actually runs, not how often you wish it did: a period shorter than the real cadence means every run is already late when the next one starts, and the monitor flaps all night for a job that is fine.
You do not have to get the period right first time
Once five gaps between successful pings are on record, the monitor compares what you declared against what the job really does, and says so when the two disagree, in either direction. An hourly job earns that verdict the same day and a nightly one after about five days. A period set too tight pages you for nothing. One set too loose leaves a dead job unnoticed for longer than it needs to be.
Say more than "alive"
The bare URL says the job reached the end. A path segment after it says what the ping means. Calling /start before the work times the run. If you pass the exit code instead, a nonzero one fails the monitor straight away rather than waiting out the period, which is the difference between hearing about it at 03:05 and at 04:15. The first 4 KB of a POST body is kept as that run's output, so piping the end of the log in puts the exit code and the lines around the failure together, instead of on a machine you have to go and find.
The job that started and hung
A plain heartbeat cannot see this one. The job began, hung, and will never ping again. Pairing /start with a finish gives the run a duration, and a max run time then catches it while it is still hanging. Without that you wait out the whole period before anything is said, which for a nightly job is a day.
The ping URL is a credential
Anyone holding it can mark the job healthy, which means anyone holding it can keep a real outage invisible. It spreads by design into crontabs, CI config and runbooks, so it needs rotating when it leaks or when someone who knew it leaves. Rotate from the monitor page or the API and the monitor keeps its incidents, history, share links and status-page placement. The old URL keeps working for 24 hours by default, because a URL that dies instantly does not alert, it just goes quiet. Watch when the old one was last used and end the overlap early. If it genuinely leaked, end it straight away.
Run it beside the checks watching your front door
A heartbeat knows one thing, whether your job reported in. It can never tell you your website is down. It sits in the same monitor list as the HTTP, TLS and domain checks watching the front door, and it reaches the same status page and the same alert channels. Heartbeat is one of the eight check kinds here, not a separate tool to run.
A nightly backup, reporting for itself
curl -fsS $URL/start # before the work
./nightly-backup.sh > backup.log 2>&1
code=$?
tail -c 4000 backup.log | curl -fsS --data-binary @- "$URL/$code"
FAQ
How do I monitor a cron job?
Why do cron jobs fail without alerting anyone?
What period and grace should I use?
Can it catch a job that starts and then hangs?
Can I see why the job failed?
What happens if the ping URL leaks?
At a glance
- Direction your job calls us
- Signals start, success, fail, exit code
- Run output POST body kept per run
- Late job period plus a grace window
- Ping URL rotatable, 24h overlap
- Price to start free, no card