Every other check here works by us fetching something. This one works the other way round: your job calls us when it finishes, and we tell you when that call stops arriving. It is the only way to catch a backup that has been silently failing for three weeks — because a job that never ran produces no error, no response and no log line to look at.
Free plan forever · No credit card · Set up in under a minute
What is a heartbeat check?
A URL your job calls when it finishes successfully. You tell us how often to expect that call and how late it may be before it counts as a failure. If the call does not arrive in time, you get an alert — email, Slack, Teams, Discord, Telegram or webhook. Nothing is installed, nothing is scraped, and the job does not need to expose anything to the internet.
A cron job that fails loudly is the easy case. The disk fills, the script exits non-zero, the error lands in a log, and something notices. The dangerous case is the job that stops being invoked at all — a crontab edited badly, a container that no longer starts, a server rebuilt without its schedule, a queue worker killed by the OOM reaper. None of those produce an error, because nothing ran to produce one.
That absence is the whole problem. You cannot alert on a log line that was never written. The only reliable signal is the one that stops: if a job has been checking in every night for a year and tonight it does not, something is wrong — and you know within minutes rather than the next time somebody needs the backup.
This is deliberately the simplest monitor here. One HTTP call at the end of your script, no agent, no credentials, no inbound access to the machine running the job.
All of these are silent by nature. None of them raise an error anybody sees.
Backups are the classic case because nobody looks at a successful one. A broken backup and a working backup produce identical evidence day to day — nothing — right up until the moment you need to restore. A heartbeat turns "no news" from an assumption into a fact.
A syntax error in a crontab line can stop the line running without stopping the others. The job simply never fires again. There is no failure to catch because there is no execution.
A scheduled task in a container that no longer comes up leaves nothing behind. The orchestrator may report the service as absent rather than failed, and absent things rarely page anyone.
A worker terminated by the kernel does not get to write a final log line. Jobs pile up in the queue, everything looks calm, and the first symptom is a customer asking why their export never arrived.
Three settings, and only one of them needs any thought.
Each heartbeat gets its own address containing an unguessable token. Calling it records a check-in. It answers to GET, POST or HEAD and needs no key, header or body, because it is called from shell scripts and CI runners that cannot be relied on to send anything in particular.
How often the job is supposed to check in — hourly, daily, weekly. This is the schedule you already have in your crontab, restated so we know what silence means.
How late the job may be before it counts as failed. This is the setting worth thinking about. A nightly backup that usually finishes at 03:00 but occasionally takes until 03:40 should have a grace window that covers the slow night, or you will be paged for a job that was merely busy. Alerts you learn to ignore are worse than no alerts.
Once the period and grace have both passed with no check-in, the job is marked late, an incident opens, and your alert channels fire. When the next check-in arrives the incident closes and you are told it recovered.
The placement matters more than anything else on this page.
Call the URL after the work has finished, not before it starts. A ping at the top of a script reports success for work that has not happened yet — and worse, keeps reporting success while the job fails on its second line every night.
In a shell, backup.sh && curl … calls the URL only when the script exits zero. If the job fails, no check-in is sent, and the heartbeat catches it exactly as if the job had never run.
Use curl -fsS -m 10 --retry 3. A monitoring call should never be the thing that hangs your backup, and a brief network blip should not manufacture a false alarm.
Heartbeats are named after the work, not the machine. Two servers running the same nightly import should have two heartbeats, or one silent server hides behind the other.
Create a heartbeat, add one line to your job, and get alerted when the job stops running.
Name it after the job — "Nightly database backup" — and set how often it should run.
Allow for the slowest run you have seen, so a busy night does not page anyone.
Each heartbeat has its own address containing an unguessable token.
Append it to the crontab line after the command, so it only runs when the job succeeds: your-script.sh && curl -fsS -m 10 https://monitoringdaddy.com/ping/your-token
A heartbeat that has never been pinged is treated as waiting, not late. Alerting starts once it has checked in at least once.
Typically about 5 minutes from start to finish.
Uptime monitors, watched pages and heartbeats each get their own allowance, so adding a page watch never costs you a monitor. SSL and domain checks ride along with the monitor they belong to and use nothing extra.
| Plan | Monitors | Watched pages | Heartbeats | Fastest interval | Alert channels | Price |
|---|---|---|---|---|---|---|
| Free | 1 | 1 | 1 | Every 30 minutes | 1 email address | $0 |
| Founding Member first 20 only | 25 | 25 | 25 | Every 5 minutes | Email + webhook & chat | $5/mo |
| Basic | 10 | 10 | 10 | Every 10 minutes | Email + webhook & chat | $8/mo |
| Growth | 50 | 50 | 50 | Every 5 minutes | Email + webhook & chat | $19/mo |
| Pro | 100 | 100 | 100 | Every 60 seconds | Email + webhook & chat | $34/mo |
Annual billing is cheaper on every paid tier. The pricing page is the authoritative list.
Every recorded change is compared word by word and kept with a before-and-after image. This is the real output, shown with worked example data.
Price fell from $49 to $39, and an annual discount was added.
The item is available again and the basket button returned.
A new subprocessor was added in another jurisdiction.
The free plan sends to one email address. Every paid plan adds the chat and webhook channels below, with 2 to 10 destinations depending on the plan. However many alerts you receive, the price does not change — nothing here is metered or charged per alert.
There are no voice calls and no SMS. If a phone call at 3am is a hard requirement, say so before you subscribe — we would rather tell you now than refund you later.
A URL your scheduled job calls when it finishes successfully. You say how often to expect the call; if it does not arrive within that period plus a grace window, the job is treated as failed and you are alerted. It is sometimes called a dead man's switch, because the alert fires on silence rather than on an error.
Because there is nothing to observe. Uptime monitoring works by fetching something and judging the response. A job that was never invoked produces no response, no exit code and no log line — the absence is the only evidence, and only something expecting a signal can notice it is missing.
At the very end of the job, and only on success. In a crontab: 0 3 * * * /usr/local/bin/backup.sh && curl -fsS -m 10 https://monitoringdaddy.com/ping/your-token. The && matters — it means the URL is only called if the script exited cleanly.
Then a heartbeat will not work, and no hosted heartbeat service will. The check depends on the job being able to make one outbound HTTPS request. Everything else — inbound access, agents, credentials — is not required.
Take the longest the job has ever legitimately taken, then add a margin. A nightly job that usually finishes in ten minutes but has occasionally taken forty should have a grace window of at least an hour. Too tight and you will be paged for slow runs until you stop reading the alerts.
Yes — anything that can run a curl command at the end of a successful run. There is nothing platform-specific about it: a CI pipeline, a Kubernetes CronJob, a Windows scheduled task and a Raspberry Pi in a cupboard all use the same one-line call.
The next check-in closes the incident and you are told it recovered, through the same channels that told you it was late. There is nothing to reset by hand.
One on the free plan, ten on Basic ($8/mo), twenty-five on Founding Member ($5/mo), fifty on Growth and a hundred on Pro. They are counted separately from uptime monitors and page watches, so adding a heartbeat never costs you a monitor.
Yes — Slack, Microsoft Teams, Discord, Telegram, Flock and generic webhooks, the same channels every other monitor here uses. Browser push is available too, so a failed overnight job can reach a phone lock screen.
Issue a new one from the heartbeat's page. The old address stops working immediately, so update the job before its next scheduled run. The token only ever identifies one heartbeat — it grants no access to the account.
No. Extra check-ins are harmless; the heartbeat only cares about the gap between them. A job that runs more often than expected will never alert, which is why the period should match the slowest legitimate schedule.
No, and they answer different questions. Server monitoring tells you the machine is up. A heartbeat tells you the work actually happened. A perfectly healthy server can fail to run a backup for months.
Last updated August 6, 2026 · Written by Amit Gupta, founder of MonitoringDaddy
The free plan includes a heartbeat, needs no card, and takes about a minute to wire into a crontab line.