Vivere

Vivere / Answers

How to know if your backup actually ran

A backup job that fails silently looks exactly like one that works, right up until the day you need it.

Backups are the classic silent failure. The job is scheduled, nobody looks at it, and the first real test is the day something is lost. Verifying a backup is three separate questions, and most setups only answer the first one.

Question 1: did it run at all?

Check the scheduler, not the backup tool:

# cron
journalctl -u cron --since "2 days ago" | grep backup

# systemd timers
systemctl list-timers --all | grep backup
systemctl status backup.service

# Windows
# Task Scheduler → the task → History tab (enable All Tasks History first)

If nothing appears, the job never started, and no amount of inspecting the destination will tell you why. See cron job not running or Windows Task Scheduler task didn't run.

Question 2: did it succeed?

Exit code zero is necessary and not sufficient. Real examples of a backup that "succeeded":

Write the job so its exit code means something:

#!/bin/bash
set -euo pipefail
pg_dump -Fc mydb > /backups/mydb-$(date +\%F).dump

Note the escaped \% if that line lives in a crontab: cron turns an unescaped % into a newline.

Question 3: is the result plausible?

The cheapest useful check is size, compared with recent runs. A dump that is 4 KB when last week's was 300 MB is a failure that exited zero.

SIZE=$(stat -c%s "$OUT")
if [ "$SIZE" -lt 10000000 ]; then
  echo "backup suspiciously small: $SIZE bytes" >&2
  exit 1
fi

Better, verify the archive can be read: gzip -t, tar -tzf … >/dev/null, or pg_restore --list on a custom-format dump. It costs seconds and catches truncation.

Best, restore it somewhere periodically. The first restore you perform should not be the one you are doing under pressure at 3am. Quarterly is a reasonable floor; monthly if the data changes shape.

The rotation trap

Retention that deletes by age rather than by count of verified backups will happily delete your last good copy while keeping a week of empty ones. If you prune, prune only after the new backup has passed its checks — and never let the pruning step run when the backup step failed.

Being told the night it does not happen

All of the above still requires someone to look. Make the backup report to something outside the machine instead, so silence becomes the alert:

#!/bin/bash
set -euo pipefail
PING="https://vivere.dev/p/<your-monitor-id>"

trap 'curl -fsS -m 10 -o /dev/null "$PING/fail"' ERR

OUT=/backups/mydb-$(date +%F).dump
pg_dump -Fc mydb > "$OUT"
pg_restore --list "$OUT" > /dev/null          # it opens
SIZE=$(stat -c%s "$OUT")
[ "$SIZE" -gt 10000000 ]                       # and it is plausible

curl -fsS -m 10 --retry 3 -o /dev/null -d "ok, $SIZE bytes" "$PING"

Now three different failures raise an alert. The dump failing hits the ERR trap and alerts immediately. The size check failing does the same. And the case no script can catch — the machine was off, the cron entry was removed, the disk was read-only, the container never started — produces no ping at all, and the missed deadline alerts on its own.

Sending the size as the ping body means the alert history doubles as a record of how the backup has been growing, which is where you notice the week it quietly halved.

Common questions

How can I tell if my backup ran last night?

Check three things, not one: that the job ran at all, that it exited successfully, and that the output is a plausible size compared with previous nights. A job that ran and exited zero can still have written an empty file if the source was unreachable.

Why do backups fail silently?

Most backup jobs are scheduled tasks whose output goes nowhere, and most scheduling systems only report a job they started. A disabled timer, a full disk, an expired credential or a machine that was off produce no output at all, which is indistinguishable from success if nobody is checking.

How often should I test a restore?

Often enough that the first restore you do under pressure is not your first restore. Quarterly is a reasonable floor for anything that matters; monthly if the data changes shape frequently. Verifying that the archive opens and contains what you expect catches most of the problems a size check does not.

Find out without looking

Vivere watches for the ping that does not arrive. Add one line to the job, pick where alerts should land, and you hear about the run that never happened.

Start free Read the quickstart

Ten monitors, a status page, email and webhook alerts. No card.

Last reviewed September 2026.

Related