Guides / Monitoring guides

Heartbeat monitoring explained (the dead man's switch)

Updated · 5 min read

What heartbeat (dead man's switch) monitoring is, how it differs from uptime checks, and how to set periods, grace and signals.

A dead man's switch is a control that triggers when the operator stops doing something. A train's driver has to keep a pedal or handle engaged, and if they let go, the brakes apply. The system doesn't try to detect every way the driver might become incapacitated. It simply requires a continuous signal and acts when the signal stops.

Heartbeat monitoring applies the same idea to software. Your job sends a signal every time it completes. A monitor expects that signal on a schedule. When it stops, you get an alert, whatever the cause.

Heartbeats vs uptime checks

There are two basic ways to monitor something:

Uptime check (pull)Heartbeat (push)
Who makes the requestThe monitor calls your serviceYour job calls the monitor
Good forWebsites, APIs, anything with a public endpointCron jobs, workflows, queues, backups, agents
Works behind a firewallOnly if the endpoint is reachableYes, outbound HTTPS is enough
Detects"The service doesn't answer""The work didn't happen"

A scheduled job has nothing to poll. It exists for a few seconds a day. Even if it had an endpoint, a healthy endpoint wouldn't prove the job ran. Heartbeats test the outcome you care about: the work completed.

Flowhush is a heartbeat monitor only. If you also need uptime checks for a website, use a separate tool or one of the services covered in the comparisons at the end.

The vocabulary

  • Ping: an HTTP request to the monitor's unique URL, e.g. https://flowhush.com/p/YOUR-MONITOR-UUID. The UUID in the URL identifies the monitor, so there's nothing else to authenticate.
  • Period: how often a success ping is expected. In Flowhush it's measured from the last successful ping, from 60 seconds to 31 days.
  • Grace period: extra time before raising the alarm, from 60 seconds to 7 days. Between period and period + grace the monitor is late, which shows on the dashboard but doesn't alert. After that it's down and you're alerted.
  • Start signal: an optional ping at the beginning of a run (/start). If the run doesn't complete within the grace period, that's a failure. This is how you catch jobs that hang.
  • Fail signal: an explicit "this run failed" (/fail). It marks the monitor down immediately instead of waiting for the deadline.
  • Recovery: the next success after a failure. Flowhush sends one alert when a monitor goes down and one when it recovers, not one per missed ping.

A new monitor stays in the new state until its first ping and sends no alerts, so creating monitors before you deploy is safe. Paused monitors don't alert either.

What heartbeats catch, and what they don't

Because the alert condition is the absence of success, heartbeats catch failures that error-based monitoring can't:

  • The scheduler stopped (crontab wiped, workflow deactivated, Zap turned off)
  • The host is down or the container never started
  • The job hangs forever (with a start signal)
  • The job exits early without raising an error
  • The job "succeeds" with bad output (with output checks on the ping body)

What a heartbeat doesn't give you on its own is why. Pair it with the job's own logs or error notifications, and send a short error message in the /fail ping body. Flowhush keeps the first 1 KB of each ping body in the monitor's Recent pings.

Choosing the period and grace

  1. Period = the normal interval between successful runs. Hourly job: 3600. Daily: 86400. Event-driven workflows have no fixed interval. Use the longest gap that is still normal, e.g. "we always get at least one order every 6 hours" gives 21600.
  2. Grace = normal variation plus maximum run time. A daily job that takes 5–40 minutes and sometimes starts late needs about an hour: 3600. With /start, grace is also the run-time limit, so it must exceed your slowest legitimate run.
  3. Irregular schedules (weekdays only, business hours) need a period that covers the longest normal gap. Flowhush uses intervals, not cron expressions, so a weekdays-only job needs a period of about 72 hours to get through the weekend. Alternatively, pause the monitor when you know nothing will run.

Being too strict leads to alert fatigue. Being too loose delays detection. When in doubt, start loose and tighten after a week of history.

Where to put the ping

The rule: ping from the job itself, after the work, only on success.

  • Don't ping from a separate keep-alive loop or a different cron entry. That proves the scheduler works, not the job.
  • Don't ping at the start of the script (use /start for that) or in a finally block that also runs on failure.
  • Make the ping unable to break the job: short timeout, a few retries, errors ignored.

Adding pings

curl (shell, cron, CI)

/usr/local/bin/do-the-work && curl -fsS -m 10 --retry 3 -o /dev/null https://flowhush.com/p/YOUR-MONITOR-UUID

With start and fail signals:

curl -fsS -m 10 -o /dev/null https://flowhush.com/p/YOUR-MONITOR-UUID/start
if /usr/local/bin/do-the-work; then
  curl -fsS -m 10 --retry 3 -o /dev/null https://flowhush.com/p/YOUR-MONITOR-UUID
else
  curl -fsS -m 10 --retry 3 -o /dev/null --data-binary "exit code $?" https://flowhush.com/p/YOUR-MONITOR-UUID/fail
fi

n8n HTTP Request node

Method: GET
URL: https://flowhush.com/p/YOUR-MONITOR-UUID
Settings → Execute Once: on
Settings → Retry On Fail: on
Settings → On Error: Continue

Place it as the last node of the workflow. For failures, an HTTP Request node in your error workflow can call the same URL with /fail appended.

Python

import urllib.request

def ping(suffix=""):
    try:
        urllib.request.urlopen("https://flowhush.com/p/YOUR-MONITOR-UUID" + suffix, timeout=10).read()
    except Exception:
        pass  # never let monitoring break the job

ping("/start")
try:
    do_the_work()
    ping()
except Exception:
    ping("/fail")
    raise

PowerShell (Windows Task Scheduler)

Invoke-WebRequest -UseBasicParsing -TimeoutSec 10 -Uri "https://flowhush.com/p/YOUR-MONITOR-UUID" | Out-Null

Testing it

Send a ping by hand and check that the monitor turns up. Then use Send test alert on the monitor page to check that your channel (email, Slack, Discord or Telegram) receives alerts. To test the full path, send a /fail ping and you should get a down alert within seconds, then a normal ping for the recovery:

curl -fsS https://flowhush.com/p/YOUR-MONITOR-UUID/fail
curl -fsS https://flowhush.com/p/YOUR-MONITOR-UUID

Missed-deadline alerts are checked every minute.

Keep the ping URL private

Anyone who has the URL can send pings to it. That can't read your data, but it could hide a real failure behind fake success pings. Keep ping URLs out of public repositories and shared screenshots, and store them like other configuration secrets. If one leaks, create a new monitor and delete the old one.

The Flowhush Free plan gives you 5 heartbeat monitors with alerts to email, Slack, Discord or Telegram, without a credit card. If you're comparing services, see Flowhush vs Healthchecks.io, Cronitor and Better Stack.

Monitor your first workflows free

The Free plan includes 5 heartbeat monitors with alerts to email, Slack, Discord or Telegram. No credit card required.

Start free — 5 monitors   See setup snippets

Sources

Third-party features and prices were checked on 3 November 2026 and may have changed since.