A 3-2-1 backup that I actually test
For years my backup strategy was a cron job I had written once and never looked at again. It ran every night, it printed nothing, and I assumed that silence meant success. When a disk finally died I found out the job had been failing since a hostname change eleven months earlier.
The setup I run now is boring on purpose. Three copies, two kinds of media, one of them off the shelf and out of the flat.
The nightly job
Each repository gets its own password file and its own systemd timer, so one broken target cannot block the other.
restic -r /mnt/usb/restic backup /srv/data /etc \
--exclude-caches --one-file-system --tag nightly
restic -r /mnt/usb/restic forget --tag nightly \
--keep-daily 7 --keep-weekly 5 --keep-monthly 12 --prune
The unit has OnFailure= pointing at a tiny service that sends me a push notification. Silence is no longer treated as success: a second timer checks that the newest snapshot is younger than 36 hours and complains if it is not.
The restore drill
On the first of every month a script picks a snapshot, restores one directory into a scratch location and compares checksums against the live copy for files that have not changed since. It takes four minutes and it has already caught one problem — a USB enclosure that silently dropped to USB 2.0 speeds and made the nightly run overlap with the next one.
| Repository | Size | Nightly run | Full restore |
|---|---|---|---|
| USB disk | 212 GB | 3–6 min | ~50 min |
| Object storage | 214 GB | 5–11 min | ~4 h on my uplink |
A backup you have never restored from is a hope, not a backup.
That four-hour number is the one worth knowing in advance. It is fine for photos. It would not be fine for anything I needed the same evening, which is why the USB disk exists at all.