The backup that proves it ran.
Nobody notices a broken backup until restore day. Give the job a heartbeat: if the ping does not arrive on time, the silence becomes an incident — with the same alerts as everything else.
1 · Create the heartbeat
In the app (Scheduled jobs → New) or via API:
curl -s -X POST https://app.upfour.io/v1/heartbeats \
-H "Authorization: Bearer $UP4_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "nightly pg_dump",
"expected_interval_seconds": 86400,
"grace_period_seconds": 3600
}'The response carries the slug — that slug is the ping URL.
2 · Size the grace window
The job runs daily (86400), but not to the second: the
dump takes 20–40 minutes depending on load. The grace window absorbs that spread —
interval = the schedule, grace = the jitter. One hour of grace on a daily backup means:
alert only when the ping is more than an hour late. Too tight pages you for a slow night; too
loose costs you reaction time.
3 · The crontab line
# m h dom mon dow command
30 3 * * * pg_dump mydb | gzip > /backups/nightly.sql.gz \
&& curl -fsS --max-time 10 --retry 3 \
https://app.upfour.io/v1/heartbeat/<your-slug>Three details carry the whole recipe:
&&, never ; | The ping must depend on the dump's exit code. With ; a failed backup still pings — the heartbeat would lie. |
-f | curl exits non-zero on HTTP errors instead of swallowing them. |
--max-time 10 --retry 3 | A hanging ping must not block cron; a transient network blip should not look like a missed backup. |
4 · What happens when it breaks
Backup fails → no ping → interval + grace passes → incident opens, your
alert plan fires,
heartbeat.missed goes out as a webhook. The next
successful ping recovers it and sends the all-clear. Every ping is logged with its timestamp
and source IP — GET /heartbeats/{id}/pings is your
audit trail for “did it really run on the 14th?”
Variants
Weekly jobs: 604800 with a day of grace. Multiple backup
hosts: one heartbeat each — a shared heartbeat can't tell you which host went quiet.
Migration downtime: pause the heartbeat, resume after; paused heartbeats never alert.