Seeing a file named something like backup-2026-10-17.sql.gz on a server feels reassuring.
But the existence of that file does not answer the real question: could we restore the system if production data disappeared or became corrupted?
When I review backups, I do not inspect one file. I inspect the whole chain: schedule, latest successful run, history, size, retention, integrity, and restoreability.
First, Check That the Backup Is Actually Recent
find /path/to/backups \ -maxdepth 1 \ -type f \ -printf '%TY-%Tm-%Td %TH:%TM:%TS %s %p\n' \ | sort -r \ | head -20I care not only that a file exists, but when it was created.
If backups are expected daily and the newest file is three days old, the strategy is already not working as expected.
The timestamp gives the first signal of a missed schedule or silent failure.
Second, Verify the Schedule Instead of Inferring It from Files
crontab -l sudo crontab -l systemctl list-timers --allThe file may have been created manually a month ago. Or the backup job may have existed before while its cron entry has since been removed.
So I verify the mechanism that is supposed to trigger backups: cron, a systemd timer, application scheduler, CI job, or another orchestration layer.
A Schedule Existing Does Not Mean the Job Completes Successfully
Configured | vTriggered | vStarted | vCompleted | vVerifiedA cron entry proves only configuration.
We still need evidence that the job actually starts and finishes with exit code 0 or another clear success signal.
If stdout and stderr disappear into nowhere, a failure can remain unnoticed for weeks.
A Backup Job Should Leave a Clear Operational Trail
2026-10-17 02:00 started2026-10-17 02:03 database dump complete2026-10-17 02:04 archive complete2026-10-17 02:04 size=1.8G2026-10-17 02:04 status=successThe log does not need to be verbose, but it should tell us when the job started, whether it completed, how long it took, and which artifact it produced.
This is especially important for silent failures where a file exists but is old or incomplete.
Backup Size Is Also a Signal
du -h /path/to/backups/* ls -lh /path/to/backups/If a database backup is usually around one size and today artifact is suddenly tens of times smaller, that is a reason to investigate before an incident.
A large size does not prove correctness either, but a sharp change from baseline often reveals an incomplete dump or a scope change.
A Compressed Backup Should at Least Pass an Integrity Check
gzip -t \ /path/to/backups/latest.sql.gzThis is still not a restore test. But if the archive cannot pass a basic integrity check, it definitely should not be considered a working backup.
An Archive Can Be Valid While the Required Data Is Missing
gzip -dc \ /path/to/backups/latest.sql.gz \ | head -100A backup command may finish without a syntax error while the dump is empty, points to the wrong database, or contains only part of the schema.
So I verify not only the container format but also a minimal semantic sign that the artifact contains the expected data.
The Main Test Is Whether the Backup Can Be Restored
backup file | vtemporary database | vrestore | vapplication-level sanity checksThe most important question is not "do we have a dump?" but "can we use it to recover a working state?"
For that I use a temporary database or isolated environment, restore the backup, and check basic invariants: tables exist, key records are readable, and rough counts look plausible.
A Restore Test Should Be Repeatable, Not One-Off Manual Magic
createdb backup_restore_check gzip -dc \ /path/to/backups/latest.sql.gz \ | psql \ backup_restore_checkThe exact command depends on the database engine and backup format.
But the principle is the same: the restore procedure should be known before an incident, not invented during one.
One Latest Backup Does Not Protect Against Logical Corruption
If corrupted data entered the database yesterday and today backup already contains the corruption, the latest artifact will not restore the system to a pre-incident state.
That is why retention history matters: multiple recovery points over time instead of continuously overwriting one file.
find /path/to/backups \ -maxdepth 1 \ -type f \ -printf '%TY-%Tm-%Td %p\n' \ | sortA Backup on the Same Server Does Not Cover Loss of the Server Itself
A local backup is useful for fast recovery after a logical mistake or failed deployment.
But if the disk fails, the server is lost, or the filesystem becomes unavailable, production data and the backup may disappear together.
So I separately verify whether another copy exists outside the primary failure domain.
A Backup Contains Production Data, So It Needs Protection Too
A backup often contains more data than any normal application endpoint would ever return in one request.
So I verify permissions, user access, storage location, transport, and encryption where appropriate. "We have a backup" should not mean "we created a new place to leak production data."
A Database Backup May Not Be Enough for Full Recovery
If the application stores user uploads, private files, or other external assets outside the database, a database dump will not restore them.
The backup scope should match the actual persistent data of the system: database, object storage, configuration secrets when they cannot be recreated elsewhere, and other irreplaceable artifacts.
Backup Failure Should Be Visible Without Manually Checking the Server
If a backup fails overnight, I do not want to discover it three weeks later during an incident.
At minimum, I want a failure log and a notification. Even better is a separate check that verifies the latest successful backup is not older than the expected interval.
I Treat Backup as Operational State, Not as a File
Expected frequency: dailyLatest run: 2026-10-17 02:00Latest success: 2026-10-17 02:04Artifact size: 1.8 GBRetention: 14 daily copiesIntegrity check: PASSLast restore test: 2026-10-12Off-host copy: YESA Restore Test Does Not Need to Run After Every Backup, but It Cannot Be Deferred Forever
A full restore every day may be expensive, but never testing restoration is more dangerous.
I want an explicit cadence: for example, regular automated integrity verification plus a periodic full restore test in a safe environment.
The exact frequency depends on data criticality and recovery cost.
My Production Backup Strategy Checklist
- The process that creates backups and its frequency are known.
- The latest successful backup is recent enough.
- Logs or another success/failure signal exist.
- The latest artifact size does not look abnormal.
- The archive passes a basic integrity check.
- There are multiple recovery points, not one file.
- A copy exists outside the primary failure domain.
- The backup scope covers all irreplaceable persistent data.
- The restore procedure is known and tested.
- The latest restore test has a known date and result.
- Backup failures become visible automatically.
A Backup Is Proven Only When Restoration Is Proven Too
A file on disk is only the artifact of one step.
A working backup strategy should create data regularly, expose failures, preserve recovery history, and provide a tested restoration path.
So during a production review, I no longer ask "do we have a backup?" I ask "what is the latest successful backup, when was it verified, and can we actually recover from it?"
A backup that has never been restored is not yet proof of recovery. It is only a file we hope will work.



