Cron job monitoring with heartbeats works like a dead man's switch: your job pings a unique URL every time it succeeds, and if the ping doesn't arrive on time, someone gets a phone call. With Edesy OnCall you create a Heartbeat monitor, copy its URL, add one curl line to your crontab, and set how often the ping should arrive. Miss the window, or report a failure, and the escalation policy starts calling.
Uptime checks can't catch this class of failure. Your website is up, your server is up, but the nightly backup stopped three weeks ago because a disk filled up or a password expired. Nothing errors. Nothing alerts. A heartbeat monitor watches for the absence of a signal.
How a heartbeat monitor decides a job failed
| Event | What OnCall does |
|---|---|
| Ping arrives on time | Monitor stays up; the period restarts |
| No ping within period + grace | Incident opens: "no heartbeat received for over 1 hour" |
Ping with ?status=fail |
Incident opens immediately, with your message |
| Next good ping after a failure | Incident resolves; paged contacts get a "back up" email |
Two settings matter:
- Period (interval): how often you expect a ping. It must match your schedule: a job that runs hourly has a 1-hour period. The shortest period follows your plan (5 minutes on Free, 60 seconds on Starter, 30 seconds on Pro) and the longest is 24 hours.
- Grace: extra time allowed before the ping counts as late, from 0 seconds to 24 hours (default 2 minutes). Set it a bit longer than your job usually takes to run, because the ping only fires when the job finishes.
Step 1: Create the monitor
In oncall.edesy.in, go to Monitors → New, choose Heartbeat, name it ("Nightly DB backup"), set the period and grace, and pick an escalation policy. The monitor page shows its URL:
https://oncall.edesy.in/hb/<token>The token is a secret. Anyone who has the URL can send pings to it, so keep it out of public repos. If it leaks, rotate the token on the monitor page and update your crontab.
Step 2: Add the ping to your crontab
Ping after the job succeeds, chained with &&:
# m h dom mon dow command
*/5 * * * * /usr/local/bin/backup.sh && curl -fsS -m 10 --retry 3 https://oncall.edesy.in/hb/<token> > /dev/nullWhat the flags do:
-fmakes curl fail on HTTP errors.-sShides the progress bar but still shows errors.-m 10stops curl after 10 seconds, so a network problem can't hang your job.--retry 3retries a dropped ping, so a brief network blip doesn't page anyone.
Because of &&, a failing backup.sh sends no ping, and the missed window raises the alert. Need a cron expression? The Cron Expression Builder shows the next run times for any schedule, and the cron heartbeat URL generator writes the full crontab line for you.
Step 3: Report failures immediately (optional)
Waiting for a missed ping can mean waiting a whole period. To get called the moment a job fails, report it:
/usr/local/bin/backup.sh || curl -fsS -m 10 "https://oncall.edesy.in/hb/<token>?status=fail&msg=backup%20failed"Or wrap it in a script that covers both cases:
#!/bin/sh
if /usr/local/bin/backup.sh; then
curl -fsS -m 10 --retry 3 https://oncall.edesy.in/hb/<token> > /dev/null
else
curl -fsS -m 10 "https://oncall.edesy.in/hb/<token>?status=fail&msg=exit%20code%20$?"
fiThe msg text (up to 200 characters) becomes the reason in the incident, the email and the call: "Nightly DB backup is down since 2:05 AM. Reason: backup failed." status=down works the same as status=fail.
One crontab gotcha: cron treats a % in a command line as a newline. Put URL-encoded messages in a wrapper script, as above, or escape each % as \% inside crontab.
What to monitor with heartbeats
| Job | Typical period | Grace |
|---|---|---|
| Database backup | 24 hours | Backup run time + margin |
| Queue worker loop | 5 minutes | 2 minutes |
| Invoice or report generation | 24 hours | 30 minutes |
| Data sync from a partner API | 1 hour | 10 minutes |
| Certificate or log rotation script | 24 hours | 1 hour |
Heartbeats work for anything that can make an HTTP request: cron, systemd timers, Kubernetes CronJobs, CI schedules, a Windows scheduled task, or a long-running worker that pings every few minutes. The endpoint accepts any HTTP method and is rate-limited to 120 requests a minute per IP, which is far more than any sane heartbeat needs.
The longest window is 24 hours plus 24 hours of grace. A weekly job can't be watched directly; add a daily ping step instead.
Who gets the call
The heartbeat monitor uses an escalation policy like any other monitor: call the job's owner first, then a backup after a few minutes, with email alongside. The call is spoken in English or Hindi, and the person presses 1 to acknowledge or 2 to escalate. See escalation policies explained.
Cost
Heartbeat monitors count towards your plan's monitor limit: 3 on Free, 20 on Starter (Rs 499/month), 100 on Pro (Rs 1,499/month). Alert calls are billed per minute from your Edesy wallet. Prices exclude 18% GST. See pricing. OnCall needs an Edesy phone number in your workspace as the caller ID.
More: heartbeat monitor docs, the cron job failure alert use case and the OnCall overview.
FAQ
What is heartbeat monitoring for cron jobs?
Your job calls a unique URL each time it finishes. The monitor expects that ping every period. If it doesn't arrive within the period plus a grace time, the job is treated as failed and the people on your escalation policy are phoned.
How do I report a failure right away?
Call the heartbeat URL with ?status=fail and an optional msg, for example when your script exits with an error. OnCall opens an incident immediately instead of waiting for the ping to go missing.
Can I monitor a weekly job?
Not directly. The heartbeat period can be at most 24 hours, plus up to 24 hours of grace. For a weekly job, add a daily ping step or monitor the job's result another way.
Does OnCall run my cron jobs?
No. Your server keeps running the jobs. OnCall only listens for the pings and calls you when one is missing or reports a failure.
Create your first heartbeat monitor free at oncall.edesy.in.