---
title: Heartbeat Monitoring: Dead Man's Switch for Jobs
description: Heartbeat monitoring for workers, daemons and scripts: each run pings a URL, and you are alerted the first time a ping is late. One curl line. Free plan.
canonical: https://watchfor.io/heartbeat-monitoring
---

# Heartbeat Monitoring: Alerts When a Service Stops Checking In

A crashed queue worker returns no error, so uptime checks stay green. Your service pings a URL each cycle, and the first late ping opens an incident.

[Get started for free](/auth/sign-up)[View pricing](/pricing)

## What a Heartbeat Monitor Does

For workers, daemons and scripts that have no public endpoint to check

### One HTTP Request per Cycle

Call https://ingest.watchfor.io/p/<token> from the worker loop or the end of a script. GET, POST, HEAD or any other method works. curl, wget or your language's HTTP client is enough: no agent, no SDK, no inbound port.

### Period From 1 Minute to 1 Year

Set how often a ping is due, anywhere from every minute (every 3 minutes on Free) to once a year, and a grace period of 0 seconds to 30 days. The deadline is one full period plus grace from the last ping, so a worker that pings every 5 minutes with 2 minutes of grace alerts after 7 minutes of silence.

### Exit Codes

Ping /p/<token>/$? and the exit code (0 to 255) travels with it. Zero is a success. Anything else, or a ping to /fail, raises Run Failed with the code in the incident, separate from Missed Schedule.

### Run Duration

Ping /start when a run begins and finish as usual; add ?rid=<id> when runs can overlap. WatchFor measures each run, charts average, min and max on the Overview, and the off-by-default Run Duration rule alerts when a run goes past your threshold.

### Output With the Ping

POST the job's output with the ping and up to 10 KB of it is stored and shown in the Pings tab next to that event. A failed run's error message is there before you open a terminal.

### Alerts on the First Miss

A heartbeat has one source of truth, so there is no multi-location confirmation: a window that closes without a ping opens a critical incident straight away, and the next ping resolves it. Alerts go out on the same 16 channels as every other monitor, including email, Slack, Telegram, Discord and PagerDuty.

### Healthchecks-Style Ping URLs

The /start, /fail and /<exit-code> suffixes and ?rid= work the way Healthchecks scripts expect. Moving a script over means replacing the old ping base URL with your WatchFor ping URL; the suffixes stay as they are.

### Ping Log

Every check-in, start, failure and missed window in one log you can filter by result, with exit code, run ID, duration and the attached output on each row.

## A closer look

Missed and failed runs are logged apart, with exit code and run duration.

Copy the ping URL, add one curl line; exit codes and run IDs are optional.

A missed schedule and a failed run are separate rules with separate alerts.

## Why Heartbeats Belong Next to Your Uptime Checks

An uptime check asks a public endpoint whether it responds. Background workers, sync jobs and internal daemons have no endpoint to ask, and when they stop, the only symptom is that something stops happening: the queue grows, the export file is not written, the replica falls behind. A heartbeat monitor turns that absence into an incident. Each one counts as a regular monitor against your plan, and heartbeat monitors are included on the Free plan.

[Start monitoring now](/auth/sign-up)

Catches workers and daemons that die without an error

One HTTP request per cycle, from cron, systemd, Kubernetes or any loop that can reach the internet

Period from 1 minute (3 on Free) to 1 year, grace from 0 seconds to 30 days

Missed Schedule and Run Failed are separate alerts, both on by default

Run duration from /start and finish pings, charted and alertable

Up to 10 KB of output stored with each ping

The first miss opens an incident; the next ping resolves it

Counts as one regular monitor, Free plan included

## How Heartbeat Monitoring Works

Your service reports in; WatchFor watches the clock

1

### Create a Heartbeat Monitor

Pick the Heartbeat card, set how often a ping is due (every 5 minutes, every hour, every day) and how late it may be before you are alerted.

2

### Add the Ping to Your Service

Copy the ping URL from the Setup tab and call it each time a cycle completes. The token in the URL is the only secret, so treat it like a password.

3

### Each Ping Resets the Timer

Every successful or failed ping starts a new window. A /start ping does not, so a job that hangs mid-run still counts as missed.

4

### A Late Ping Opens an Incident

When the window plus grace runs out, Missed Schedule opens a critical incident and your channels and on-call fire. The root cause shows the schedule that was expected and that no ping arrived.

## What Teams Watch With Heartbeats

If it should run regularly, it can check in regularly

### Queue Workers and Consumers

Sidekiq, Celery, BullMQ or your own consumer: a crashed worker lets the queue grow for hours. Ping once per processed batch or once a minute from the main loop, and a stopped worker alerts after one period plus grace.

### Backups and Data Syncs

A backup script that stopped running three weeks ago looks exactly like one that works, until you need a restore. Ping at the end with the exit code and the script's output, and a failed or skipped run is an incident the same day. For jobs on a fixed clock, use a cron job monitor instead.

### Daemons and Internal Services

A service with no public endpoint cannot be checked from outside. A ping from its main loop shows that it is not only running but still getting through its work.

### IoT Devices and Edge Boxes

Devices behind NAT and firewalls cannot be reached by an active check, but they can make an outbound request. One heartbeat per device tells you which unit went quiet and when.

## Frequently asked questions

Everything you need to know about heartbeat monitoring

[All questions→](/faq)[Ask us directly](/contact)

What is heartbeat monitoring? Heartbeat monitoring, also called a dead man's switch or passive monitoring, reverses the usual direction of a check. Instead of WatchFor probing your system, your system pings a unique URL each time it completes a cycle of work. If no ping arrives within the expected period plus a grace period, an incident opens. It catches failures whose only symptom is silence.

How is this different from regular uptime monitoring?

How do I send a ping?

What is the grace period for?

Can I tell “didn't run” apart from “ran but failed”?

How does run duration tracking work?

Is the ping URL secure?

Can I pause alerts while a job is down on purpose?

Can I create heartbeats from code?

How much does heartbeat monitoring cost?

## From our blog

Guides, deep-dives, and best practices from the WatchFor team

[Monitoring

### Six scheduled jobs that will eventually burn you — and the exact check-in for each

Aug 23, 2026·5 min readRead article](/blog/cron-monitoring-recipes)[Monitoring

### Heartbeat & Cron Job Monitoring: the Dead Man's Switch Your Backups Deserve

Jul 30, 2026·6 min readRead article](/blog/heartbeat-cron-monitoring)[Reliability

### Alert Fatigue: why your team stopped reading alerts (and how to fix it)

Jun 25, 2026·5 min readRead article](/blog/alert-fatigue)

## Hear From Every Worker

Create a heartbeat monitor, paste one curl line into the worker or script, and the first late ping opens an incident. Start on the Free plan, no credit card required.

[Get started for free](/auth/sign-up)[View documentation](/docs/monitors/heartbeat)

---

Canonical page: https://watchfor.io/heartbeat-monitoring · Site guide: https://watchfor.io/llms.txt
