Cron Heartbeat Monitors

Get a phone call when a cron job, backup or worker doesn't run. Ping your Edesy OnCall heartbeat URL from crontab with curl, report failures with ?status=fail, and set the period and grace time.

3 min read

A heartbeat monitor (also called a dead man's switch) waits for your job to check in. Your cron job, backup script or worker requests its heartbeat URL each time it finishes. If no ping arrives within the period plus the grace time, the monitor goes down and OnCall starts calling.

This catches the failures other checks miss: a cron daemon that stopped, a server that was rebuilt without its crontab, or a job that hangs and never finishes.

Your heartbeat URL#

Each heartbeat monitor has its own secret URL, shown on the monitor's page with ready-to-paste snippets:

https://oncall.edesy.in/hb/<token>
  • Any HTTP method works (GET, HEAD, POST). The response is ok.
  • Add ?status=fail (or ?status=down) to report a failure right away, without waiting for the ping to go missing.
  • Add &msg=... with a short reason (up to 200 characters). It appears in the incident and is read out on the call.
  • An unknown token answers 404 unknown heartbeat URL.
  • Requests are limited to 120 a minute per IP address.

Settings#

Field Meaning Values
interval_sec How often the job runs (the period you expect pings) Your plan's minimum up to 86,400 (24 hours)
grace_sec Extra time allowed before the monitor goes down 0 to 86,400; default 120

The monitor goes down when last ping + period + grace has passed. A ping that arrives after that brings the monitor back up and resolves the incident.

Set the grace to at least how long the job usually takes, plus a margin. A nightly backup that runs for 40 minutes might use a period of 24 hours and a grace of 60 minutes.

Because the period can't be longer than 24 hours, a heartbeat suits jobs that run at least once a day. The plan minimum also applies: on Free the shortest period is 5 minutes, so a job that runs every minute needs Starter or Pro.

Cron job#

Ping after the job succeeds. -f makes curl fail on HTTP errors, so a broken job sends no ping.

# 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/null

Report a failure now#

Don't wait for the ping to go missing: tell OnCall the job failed and why.

/usr/local/bin/backup.sh || curl -fsS -m 10 "https://oncall.edesy.in/hb/<token>?status=fail&msg=backup%20failed"

Inside a crontab line, % has a special meaning (cron turns it into a newline). Either escape it as \%, or let curl encode the message for you:

0 2 * * *  /usr/local/bin/backup.sh || curl -fsS -m 10 -G --data-urlencode "status=fail" --data-urlencode "msg=backup failed" https://oncall.edesy.in/hb/<token>

Shell script#

Wrap any script: ping on success, report the failure otherwise.

#!/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$?"
fi

The free Cron Heartbeat URL Generator builds these lines for your schedule and command.

Keep the URL private#

Anyone with the URL can send pings, and a fake success ping could hide a real failure. Keep it out of public repositories. If it leaks, press Rotate token on the monitor page; the old URL stops working at once, so update your crontab with the new one.

FAQ#

What if my job runs but fails? Use && so curl only pings on success, or send ?status=fail from the failure branch. A failure report opens an incident immediately.

Can I monitor a weekly job? Not reliably: the longest period is 24 hours (plus up to 24 hours of grace). Heartbeats suit jobs that run daily or more often.

Do I need curl? No. Any HTTP request works: wget, PowerShell's Invoke-WebRequest, or an HTTP call from your application code.

Does the heartbeat URL need an API key? No. The secret token in the URL identifies the monitor.

Was this page helpful?