Heartbeat monitoring for cron jobs

How to detect a cron job or worker that silently stopped with heartbeat (dead man's switch) monitoring: interval, pings, missed heartbeats, incidents, and recovery.

The problem with cron

A cron job that stops running produces no error. The server rebooted, the crontab was lost in a deploy, the container never started, or the job hangs. Nothing alerts you because nothing failed loudly, and uptime monitoring cannot see it: there is no URL to poll.

What a heartbeat monitor does

You tell Flowyn how often the job runs (interval_seconds). The job pings Flowyn at the end of every successful run. If no ping arrives within twice the interval, Flowyn records a missed heartbeat; three consecutive misses open an incident. The next ping closes it. Every ping is recorded.

Create the heartbeat

curl -X POST https://api.flowyn.dev/v1/monitors \
  -H "Authorization: Bearer $FLOWYN_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: hb-nightly-backup" \
  -d '{
    "name": "Nightly backup",
    "type": "heartbeat",
    "method": "GET",
    "url": "",
    "interval_seconds": 86400,
    "timeout_ms": 1000,
    "assertions": []
  }'

Ping from the job

Put the ping at the end of the job so a crash before completion shows up as a missed heartbeat. The ping needs your API key, so keep it in the job's environment.

bash
#!/bin/sh
set -e
pg_dump mydb | gzip > /backups/$(date +%F).sql.gz
curl -fsS -X POST https://api.flowyn.dev/v1/monitors/1a6d8f2c-5b3e-4a9d-8c7f-6e0b2d4a1c95/ping \
  -H "Authorization: Bearer $FLOWYN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

A job that knows it failed can say so with {"status":"failed","error":"disk full"} instead of staying silent.

Choosing the interval

Jobinterval_seconds
Every-5-minutes worker300
Hourly sync3600
Nightly backup86400

Set the interval to how often the job should run. The twofold window absorbs normal jitter; a job that runs less often than daily needs another signal, because the maximum interval is 24 hours.

What you read back

  • current_status of the monitor
  • Results with GET /v1/monitors/{id}/results
  • Incidents with GET /v1/monitors/{id}/incidents

Combine with schedules

If the cron itself is the weak part, move it to a Flowyn schedule. Each occurrence becomes a durable HTTP job with attempts, and missed occurrences are skipped rather than backfilled. Keep the heartbeat as an independent check.

Next step

Read how Flowyn groups repeated failures into Issues.