CronPup

← Guides

How to know your backups actually ran

Everyone has a backup job. Far fewer people know whether it ran last night. Backups fail quietly: an expired cloud credential, a full disk, a renamed database, a cron line lost in a server rebuild. The failure only surfaces during a restore, which is the worst possible moment.

Step 1: make the backup report success

Add a heartbeat ping that fires only when the backup command exits successfully:

0 2 * * *  pg_dump -Fc mydb > /backups/mydb-$(date +\%F).dump && curl -fsS -m 10 https://cronpup.com/p/YOUR-UUID

Note the escaped \%. In a crontab, a bare % means "newline", which is a common reason backup lines silently break.

Step 2: fail loudly on a bad result

An exit code of 0 doesn't always mean a usable backup. Add a sanity check, such as a minimum size, and report a failure if it doesn't pass:

#!/bin/sh
set -eu
URL=https://cronpup.com/p/YOUR-UUID
curl -fsS -m 10 "$URL/start"
OUT=/backups/mydb-$(date +%F).dump
if pg_dump -Fc mydb > "$OUT" && [ "$(stat -c %s "$OUT")" -gt 1000000 ]; then
  curl -fsS -m 10 --data-raw "size=$(stat -c %s "$OUT")" "$URL"
else
  curl -fsS -m 10 --data-raw "backup too small or failed" "$URL/fail"
fi

The POST body is stored with the ping, so the monitor's history doubles as a log of backup sizes.

Step 3: monitor the off-site copy too

If you sync backups off-site with rclone, restic or aws s3 sync, give that step its own monitor. A local backup that never leaves the server dies with the server.

Step 4: test restores

Monitoring proves the job ran. Only a restore proves the backup works. Schedule a monthly restore test, and monitor that job too.

Monitor your backups with CronPup. 10 monitors are free.