Backups, migration and recovery: a backup you have not restored is a rumor.
Five things to protect, four recovery paths, and a timed drill using this site's data. See what came back, what was measured, and what still needs an application-level test.
Five stores to protect. Caches to rebuild.
A WordPress site is five stores and a pile of caches. A backup is a copy of the five. A restore drill is proof that each copy comes back. Here is the inventory for the site you are reading, with what has been proven and what has not.
| Store | What it holds | How it is protected | How it comes back |
|---|---|---|---|
| Codeobserved at boot | Core, theme, plugins, mu-plugins, layout manifests, infrastructure YAML. 20,077 files | A git repository with a protected production branch | Every pod boot fetches the branch. A rollback is a revert and a push |
| Database✓ component tested | Posts, options, users, the page layouts. 456 MB, 49 tables | Nightly Cloud SQL backup, seven retained, seven days of transaction logs, and a regional standby | A point-in-time clone within the available recovery window, or a backup restore |
| Media✓ component tested | 863 items, 1.4 GB with every generated size | Object versioning plus a seven-day soft delete on the bucket | Copy the previous generation back over the object |
| Configuration○ not drilled here | The deployment, autoscaler, CDN distribution and database instance as YAML | Checked into the repository, applied by a workflow on push | Re-apply from the repository. 22 distributions were once rebuilt this way on client sites |
| Secrets○ not drilled here | Database credentials, deploy keys, API tokens | Versioned secrets in Secret Manager, with access managed separately | Resolve available versions at boot. Rebuilding after loss of the secret store or its access policy needs a separate recovery plan |
| Rebuildable state– by design | Object and page caches, plus disposable container files | Excluded only when they contain no unique data | Warm caches through traffic. Inventory sessions, queues and plugin files first; anything irreplaceable needs protection |
Status distinguishes component tests from observations during normal operation. Neither proves a complete site recovery. The drill ran on October 12, 2026 (UTC).
Seventeen minutes, timed, on this site.
Run on October 12, 2026, 01:26 to 01:44 UTC (October 11 evening in New York). A separate database clone and a scratch media object kept the live application untouched. This is a component recovery drill, not a measured site recovery time.
Completed 01:28:24. The nightly backup is automatic; this one was taken before a content change, the way every layout write on this site is preceded by one.
The clone reached RUNNABLE at 01:38:50 and its databases were listed. That establishes provisioning and recovery to one selected point, not application correctness or every point in the retention window.
The 6.6 seconds include deletion, version listing and copying back a 56.1 KB test object. This used Object Versioning, not soft-delete recovery; restoring the full media library was not timed.
47.9 MB compressed from 456 MB on disk. A portable copy you can load anywhere, including a laptop.
The clone inherited the production instance's deletion protection. A drill that cannot clean up after itself is a drill nobody repeats.
Gone at 01:43:58. Total wall time for the drill, from first backup to last cleanup: 17 minutes.
What the drill proved
- A clone restored to one selected point twenty minutes earlier reached RUNNABLE in 8 min 3 s, and its databases could be listed.
- A scratch media object was deleted and copied back from its saved generation in a 6.6-second sequence.
- A logical export of the cloned production database completed in 34 seconds and produced a 47.9 MB compressed file. Importing that export was not tested.
What it did not prove
- That WordPress works against the restored database. No application was connected to the clone and no regression suite ran against it.
- That configuration and secrets can be rebuilt from scratch into an empty project. The evidence for that lives in the client record, not in this drill.
- That anyone on the team can do it from the runbook alone, without the person who wrote it.
- A full media restore, recovery from soft deletion, or the total time and data loss involved in returning the site to service.
Four failures, four clocks.
Recovery is not one procedure. It is four, and they have very different clocks. Match the failure to the store before anyone touches a backup.
Revert the incompatible code and roll out the replacement. Check database compatibility first. Deployment rollout settings and readiness govern traffic; a disruption budget does not control a rolling update.
62 to 74 secondsobserved per-pod readiness, not total rollback timeRestore a separate clone, compare the affected data and choose a repair or a controlled cutover. Reconcile valid writes made after the recovery point before replacing live data.
8 minutes to the clonemeasured, plus the switchCopy the saved object generation to a live path, verify it, then purge affected CDN variants. The drill covered one scratch object.
6.6 secondsdelete, list and copy-back sequence, CDN purge not timedRebuild infrastructure and access, restore the data and media, deploy code, then verify application behavior and traffic routing.
Hours, not minutesestimated, not drilled here, the gap this chapter exists to closeReference: Cloud SQL point-in-time recovery and Kubernetes disruption and rollout behavior. Check the available recovery window before choosing a timestamp.
Six steps, with writes accounted for.
A migration is a restore plus a cutover plan. The source and destination diverge as soon as new writes arrive. The plan must account for that gap before anyone changes a connection string.
Create the target database and storage, restore a recent copy, and connect an isolated test environment. Block outbound email, payments and scheduled jobs that could affect real users.
Run the regression suite and editorial checks. Verify uploads, logins, scheduled jobs and critical transactions. Confirm engine, plugin and schema compatibility.
Use supported replication or change capture to catch up, or schedule a write freeze and take a final consistent export and media sync. A quiet hour is not a synchronization strategy.
Pause writers for the final handoff, verify replication lag or the final import, then switch the application. Clear environment caches and affected CDN paths. Verify critical reads and writes before reopening traffic.
Keep the old source protected and read-only for the agreed retention period. Once the destination accepts writes, switching back requires reconciliation; the old copy is no longer a lossless undo button.
Check record counts, media access, errors and real application flows. Remove old credentials and infrastructure only after acceptance and the rollback window. Record the actual disruption and data-loss window.
Two incidents from the operating record.
Moving a media bucket
A bucket move left old absolute URLs in thousands of posts.
The correctionRewrite the URLs at render time, then purge the CDN. This incident was resolved without a database search-and-replace.
Sharing a database across environments
A development environment connected to the live database wrote its own hostname into 57 rows.
The correctionRestore the affected data from a backup. Content environments may share a database; anything that runs migrations gets a clone first.
You are reading the example.
This handbook is served by the system it describes, so the drill above is also a review of our own setup.
Nightly, plus seven days of log.
Automated backups at 06:00 UTC with seven retained, binary logging on, seven days of transaction log, a regional standby. A clone to one chosen point in the available window took eight minutes. A regional standby addresses availability; it does not undo an accidental data change.
Versioned and soft-deleted.
Object versioning has been on since the bucket was created in 2019; the seven-day soft delete arrived with the platform default in 2024. The delete, version-list and copy-back sequence for one scratch object took 6.6 seconds. Soft-delete restoration was not tested.
Git, applied by a workflow.
Every pod fetches the production branch at boot. The deployment, autoscaler, CDN distribution and database instance are YAML in the same repository. Page layouts are kept as manifests next to them.
A drill that includes the application.
No environment was pointed at the clone. The regression suite was not run against restored data. Configuration and secrets were not rebuilt into an empty project.
Asked after the first scare.
How often should a WordPress database be backed up?
Set the schedule from your recovery point objective: how much valid data you can afford to lose. Daily backups may suit a low-change publication, but orders or frequent edits need a smaller window. Point-in-time recovery can bridge backups while logs remain available. Verify the actual recoverable window and test the restore.
Is a backup plugin enough?
A well-configured plugin can make useful off-site backups. It still needs independent recovery instructions and access if WordPress will not start. This site protects the database and media at their storage layers, keeps code in git, and treats configuration and secrets as separate recovery dependencies.
What should a WordPress backup include besides the database?
Protect media, versioned code, infrastructure definitions, DNS and the secrets needed to reconnect the application. Keep recovery access separate from the failed environment. Exclude caches only after confirming that sessions, queues and plugin files contain no unique state.
How do I test a restore without touching production?
Restore to a new instance or scratch storage, then connect an isolated non-production application. Disable outbound email, payments and jobs, run checks, and record elapsed time and data loss. This drill timed a database clone and one object recovery; the application verification step is still outstanding.
How do I migrate a WordPress site without downtime?
Use a tested destination and a defined write-transfer method. Supported replication can minimize the handoff; otherwise a write freeze and final consistent export create a deliberate interruption. Verify the destination before reopening writes. Keeping the old source helps rollback only if you also plan how to reconcile writes accepted after cutover.
Never timed a restore on your own site?
Tell us where the database, media and code live and how much disruption the business can tolerate. We can scope a recovery exercise, test the application against restored data and document a runbook your team can use.