Website backups: what 'restore' actually means
Ask a hosting provider whether your site is backed up and the answer is always yes. Ask what happens next — what you'd actually do at 2 p.m. on a Wednesday when the pricing page is wrong and the last known-good version is Monday's — and the answers get vague.
"Backed up" is a checkbox. "Restored" is a procedure, with a clock running. A website is a specific and awkward thing to bring back, because it isn't one artifact. It's three, and they have to agree with each other.
The three parts, and why they drift apart
The database. Pages, products, orders, users, settings. It changes constantly and it's the part with real business consequence.
The uploads. Images, PDFs, attachments. These are files on disk, and the database only holds paths to them. A row says /uploads/2026/03/bench.jpg; if that file isn't in the restored set, the row survives and the page shows a broken image.
The configuration. The web server vhost, the TLS setup, cron entries, the service definition, environment variables and API keys, the DNS records, the mail authentication. Almost nobody backs this up, because it doesn't live inside the site. It's also the part that turns a two-hour restore into a two-day one, because it gets rebuilt from memory.
Restore the database from Monday and the uploads from Wednesday and you get a site full of broken images and missing orders. They have to be captured together, or close enough together that the mismatch doesn't matter.
A file copy of a running database is not a backup
This is the one that quietly ruins otherwise sensible setups. Nightly job copies /var/www to object storage. The database files are in that tree, so the database is covered, right?
No. A database engine is writing to those files continuously: pages half-flushed, transactions mid-commit, indexes out of step with data. Copy them at an arbitrary instant and you get a torn file. It exists, it's the right size, and the engine either refuses to open it or opens it corrupt. You will discover this on the day you need it.
Dump the database with the engine's own tool instead, which produces a point-in-time consistent copy while the site keeps running:
mysqldump --single-transaction --quick mysite > mysite.sql
pg_dump -Fc mysite > mysite.dump
sqlite3 app.db ".backup '/backups/app.db'"
For SQLite there's a further trap: in WAL mode, recent commits live in a separate app.db-wal file. Copy only app.db and you have a database that opens cleanly, looks fine, and is missing the last few hours of writes — the worst kind of failure, because nothing announces it.
The restore you'll actually be asked for
Here's the part that reframes the whole exercise. Almost nobody ever asks for the restore that disaster-recovery plans are built around. In years of running sites, the "the server is gone, rebuild it" event is rare. The request that comes in constantly is small and urgent:
Someone deleted the wrong page an hour ago. Can you get it back — without undoing everything else that happened today?
A full machine image can't answer that. Roll the whole box back four hours and you have destroyed every order, form submission, and content edit made since. So the actual skill is a partial restore: pull yesterday's dump into a scratch database alongside production, find the row, and copy it across. Which means your backups need to be things you can open and read selectively — plain dumps and file trees — not an opaque appliance image whose only verb is "restore everything."
Design for that first. The whole-site rebuild is the rarer case and it falls out of the same materials anyway.
Rehearsing it
A restore you haven't performed is a hypothesis. Rehearse it on a schedule, and rehearse the whole thing — database, uploads, config — onto a machine that isn't production, under a hostname that isn't production.
Two things bite during that rehearsal, so know them in advance. Sites store absolute URLs in the database, so a restored copy will happily link and redirect back to the live site unless you rewrite them. And a restored copy is fully wired for email: bring one up with its real credentials and it can fire order confirmations, password resets, and abandoned-cart mail at real customers from a copy of last week's data. Point the restored copy at a test mail sink before it comes up, not after.
What to do
- Write down your recovery point. Nightly dumps mean "we can lose up to 24 hours of orders." If that sentence is unacceptable, take the database more often — hourly dumps of a small site cost almost nothing.
- Confirm the database is being dumped, not file-copied. One command tells you which.
- Get the config into version control — vhost, service file, cron, DNS as a written record. Secrets go in a secret store, not the repo.
- Do one rehearsal end to end and time it. That number is your real answer to "how long would we be down."
Then when the Wednesday call comes, the question is which version you want back, not whether it's possible.
Not sure whether your current backups would survive that Wednesday? Send us the details and we'll tell you honestly.
Need this kind of thinking applied to your own setup? Get in touch →