Your cron job failed three days ago. You just found out. Sound familiar?
Silent cron failures are one of the most common — and most preventable — causes of production incidents. A backup job stops running, a data sync breaks, an invoice generator dies quietly. By the time anyone notices, the damage is done.
This guide covers everything you need to know about monitoring cron jobs: why they fail, how to detect failures, and the best tools to set up dead-simple monitoring in under 5 minutes.
Cron itself has no built-in concept of "this should have run but didn't." Common failure modes include:
The pattern is always the same: nothing alerts you. You find out when a customer complains or when you manually check.
The most reliable way to monitor cron jobs is the dead man's switch (also called heartbeat monitoring or check-in monitoring):
This catches every failure mode: crashes, hangs, server issues, even "someone deleted the crontab" scenarios. If the job doesn't run, the ping doesn't happen, and you know immediately.
Add a single curl call to the end of your cron job:
# Before: just the job
0 * * * * /usr/local/bin/backup.sh
# After: ping on success
0 * * * * /usr/local/bin/backup.sh && curl -fsS https://cronping.grabshot.dev/api/ping/YOUR_CHECK_ID
&& (not ;) so the ping only fires on success. If your backup script exits with a non-zero code, the ping won't send, and you'll get an alert.
For jobs that take minutes or hours, ping at the start AND end:
# Ping start, run job, ping end (or fail)
0 2 * * * curl -fsS https://cronping.grabshot.dev/api/ping/abc123/start && \
/usr/local/bin/big-export.sh && \
curl -fsS https://cronping.grabshot.dev/api/ping/abc123
This lets you detect jobs that started but never finished — the classic "hanging job" problem.
| Tool | Free Tier | Starting Price | Best For |
|---|---|---|---|
| CronPing | 5 monitors | $9/mo | Developers who want a simple API |
| Healthchecks.io | 20 monitors | $20/mo | Open-source self-hosters |
| Cronitor | 5 monitors | $24/mo | Teams with many jobs |
| Better Uptime | 10 monitors | $29/mo | Combined uptime + cron monitoring |
| Dead Man's Snitch | 1 monitor | $5/mo | Minimal, one critical job |
Set up heartbeat monitoring for your cron jobs in 30 seconds. No credit card required.
Start Monitoring Free →If your scheduled jobs run in Node.js (using node-cron, Agenda, Bull, or similar), wrap them with a ping:
const cron = require('node-cron');
cron.schedule('0 * * * *', async () => {
try {
await runMyJob();
// Ping on success
await fetch('https://cronping.grabshot.dev/api/ping/YOUR_CHECK_ID');
} catch (err) {
console.error('Job failed:', err);
// No ping = alert fires automatically
}
});
import requests
import subprocess
def run_and_ping(command, check_url):
result = subprocess.run(command, shell=True)
if result.returncode == 0:
requests.get(check_url, timeout=10)
else:
raise Exception(f"Job failed with code {result.returncode}")
# Usage
run_and_ping(
"python /app/daily_report.py",
"https://cronping.grabshot.dev/api/ping/YOUR_CHECK_ID"
)
Once you have cron monitoring set up, extend the pattern to other scheduled processes:
Cron job monitoring is one of those things that takes 5 minutes to set up and saves you hours of debugging. The dead man's switch pattern is simple, reliable, and catches every type of failure.
Pick a tool, add a curl call to your cron jobs, and stop worrying about silent failures. Your future self will thank you.
CronPing is free for up to 5 monitors. Set up in 30 seconds.
Get Started Free →