# A WordPress maintenance checklist with restore testing

Check backups, logs, security releases and key pages every week. Update on staging first and clean up plugins and users every month. Every quarter, restore the whole site onto a copy with a timer running and compare it with a baseline. In our drill, a wiped test site was back and verified in 34.2 seconds, and the drill showed which files the backup had missed.

## Key takeaways

- A backup is only proven once you restore it: run a timed restore drill on a non-production copy every quarter.
- Our wiped 13-post test site was restored and verified against its baseline in 34.2 seconds, with counts, media hashes and 7 URLs matching.
- The drill lost a file in the WordPress root, because the backup covered only wp-content and wp-config.php.
- Back up the database, wp-content, wp-config.php, root files and a record of the WordPress and PHP versions.
- Every task on the checklist names the fault it catches, so you can tell which checks you can skip and which you cannot.

## Why does a maintenance checklist need a restore test?

A backup you have never restored is a guess. Many maintenance checklists stop at “backups are running”. A running job can still leave out the database, skip a folder or save files nobody can open. You find out on the worst day, when the site is down.

This checklist is built around one quarterly task: restore the site from backup and prove it works, with a clock running. Below is the drill we ran on November 11, 2026, with every command and timing. Then come the weekly, monthly and quarterly tasks, each with what it catches, and a printable version at the end. If you want this done for you, it is the core of our [website maintenance and care plans](/services/website-maintenance/).

## What happened when we wiped a WordPress site and restored it?

We built a small test site, backed it up, deleted the whole site folder and restored it from the backup alone. The process follows the studio’s own restore-drill and WordPress update runbooks. Back up, restore into a copy that is not production, verify with counts and record the time.

## Tested on

WordPress 7.1.4 on PHP 8.3 in a local WordPress Playground site (CLI 3.1.62) on Windows 10 Pro, port 18422, November 11, 2026. Playground stores the database in SQLite, so our database export and import commands differ from a MySQL host. The MySQL equivalents are shown after the drill.

### What was on the site before the backup?

We added 12 posts, 3 pages and 2 uploaded images, activated a plugin and changed the site title. A lab script printed this baseline, including a short SHA-256 hash of every uploaded file:

```
blogname: Restore Drill Clinic
posts published: 13
pages published: 4
attachments: 2
active plugins: hello.php
permalink_structure: /%year%/%monthnum%/%day%/%postname%/
users: 1
upload files: 6
2026/11/drill-blue.png c98f574e7e10
2026/11/drill-orange.png b3b487f46f55
(4 resized copies omitted)
200 /
200 /about/
200 /services/
200 /contact/
200 /wp-content/uploads/2026/11/drill-blue.png
200 /wp-content/uploads/2026/11/drill-orange.png
200 /wp-login.php
```

The counts include the default “Hello world” post and “Sample Page”. WordPress also creates two resized copies of each image, which is why 2 uploads became 6 files.

### How did we take the backup?

Three parts, taken while the site was running: a SQL export of the database, an archive of `wp-content` plus `wp-config.php`, and a checksum file.

```
# 1. Database export (SQLite here; see the MySQL version below)
python -c "import sqlite3,sys; c=sqlite3.connect(sys.argv[1]); open(sys.argv[2],'w').write('\n'.join(c.iterdump()))" "$DB" backups/db-2026-11-11.sql
# 2. Files: wp-content and wp-config.php, without the live database file
tar -czf backups/files-2026-11-11.tar.gz -C wordpress --exclude='wp-content/database/.ht.*/.ht.sqlite*' wp-content wp-config.php
# 3. Checksums, so the restore can prove the files are intact
sha256sum db-2026-11-11.sql files-2026-11-11.tar.gz > SHA256SUMS
```

```
db export 0.15s, files archive 0.60s, checksums 0.18s
     174 SHA256SUMS
  173684 db-2026-11-11.sql
13328395 files-2026-11-11.tar.gz
```

WordPress core files are not in the backup. Any release can be downloaded again from wordpress.org, so the backup only needs to record which version ran.

### How long did the restore take?

We stopped the site and deleted the entire `wordpress` folder: core, content, database and configuration. Then we restored it step by step with a timer:

```
sha256sum -c SHA256SUMS
curl -s -o wordpress-7.1.4.zip https://wordpress.org/wordpress-7.1.4.zip
echo "$(curl -s https://wordpress.org/wordpress-7.1.4.zip.sha1)  wordpress-7.1.4.zip" | sha1sum -c
unzip -q wordpress-7.1.4.zip && rm -rf wordpress/wp-content
tar -xzf backups/files-2026-11-11.tar.gz -C wordpress
python -c "import sqlite3,sys; c=sqlite3.connect(sys.argv[1]); c.executescript(open(sys.argv[2]).read())" "$DB" backups/db-2026-11-11.sql
```

```
verify backup checksums: 0.13s
download + verify WordPress 7.1.4 core: 10.96s
unpack core: 4.05s
unpack wp-content + wp-config: 0.25s
rebuild database from SQL export: 0.15s
total before start: 15.55s
start WordPress on restored files (Playground boot): 8.1s
verification (counts, checksums, 7 URLs): 10.55s
```

From the first restore command to a verified site took 34.2 seconds. That is for a 13-post test site with a 37.2 MB core download. A real site with gigabytes of media takes far longer, which is exactly why you time your own.

We ran the same verification script and compared its output with the baseline:

```
diff a27-baseline.txt a27-after-restore.txt && echo "IDENTICAL to baseline"
```

```
IDENTICAL to baseline
```

Posts, pages, media, plugin state, site title, permalinks and all 7 URLs matched.

### What did the drill catch?

One file did not come back: a small helper script we had placed in the WordPress root folder, next to `wp-config.php`. The backup covered `wp-content` and `wp-config.php` only, so anything else in the root was gone.

On a real site, that root folder often holds files that matter. Examples: `.htaccess` rewrite and security rules, a static `robots.txt`, search console verification files and payment provider domain files. The drill found the gap in under a minute. A real outage would have found it after the restore, with the site half working. Add those files to your backup list, or confirm your host’s backup includes the whole account.

### What are the commands on a normal MySQL host?

Most hosts run MySQL or MariaDB. These are the documented equivalents. We did not run them in this drill, because Playground uses SQLite.

```
# Export with WP-CLI, or with mysqldump in a single transaction
wp db export backups/db-$(date +%F).sql
mysqldump --single-transaction -u USER -p DBNAME > backups/db-$(date +%F).sql
# Import into a staging database, never over production during a drill
wp db import backups/db-2026-11-11.sql
```

## How do you run a restore drill on your own site?

Use the same shape as our drill, scaled to a real site. The rule that matters most: restore onto a copy, never over production. A drill that overwrites live orders is an incident, not a test.

## Steps

- ### Record a baseline

Before the backup, write down counts that would reveal a bad restore: published posts and pages, media items, orders, users, active plugins and the site title. Save the list of 5 to 10 key URLs you will load afterward.

- ### Pick the backup you would really use

Take the newest copy from wherever your backups actually live, such as the host panel, a backup plugin or remote storage. Do not take a fresh one just for the drill; you are testing the routine.

- ### Restore onto a staging copy

Use a staging site, a spare subdomain or a local copy. Start the clock when you begin and note each step, including waiting for support or finding passwords.

- ### Compare with the baseline

Rerun the counts and load the key URLs. Open a few images and one older post. Check that forms send and that the login works.

- ### Write one log line

Record the date, the backup used, the minutes taken, what matched and what was missing. Open a task the same day for anything missing.

On a MySQL host with WP-CLI, these documented commands give quick counts for the baseline. We did not run them here.

```
wp post list --post_type=post --post_status=publish --format=count
wp post list --post_type=page --post_status=publish --format=count
wp post list --post_type=attachment --format=count
wp plugin list --status=active --field=name
```

## What must a WordPress backup include?

## Backup contents

| Part | Why it matters | Common miss |

| Database | Posts, pages, orders, users and settings. | A files-only backup. |

| wp-content/uploads | Every image and file you uploaded. | Excluded to save space. |

| Plugins, themes, mu-plugins | Exact versions, plus paid plugins you cannot redownload easily. | Must-use plugins skipped. |

| wp-config.php | Database settings, keys and salts. | Kept only on the server. |

| Root files | .htaccess, robots.txt, verification files. | Not in wp-content backups. |

| Version record | WordPress and PHP versions to restore onto. | Never written down. |

Store at least one copy away from the server and away from the hosting account. A backup on the same server dies with the server. Keep several dated copies, so a fault you notice late can still be rolled back.

## What should you check every week?

| Weekly task | What it catches |

| Confirm the last backup finished and has a sensible size | A job that silently stopped or saved an empty file. |

| Read Site Health and the PHP error log | New fatal errors, deprecation notices and failed scheduled tasks. |

| Apply security releases for core and plugins | Known vulnerabilities with public exploits. |

| Load the homepage, a form and checkout | Broken money pages that uptime checks miss. |

| Check uptime alerts and SSL expiry dates | Short outages nobody reported and certificates near expiry. |

Run these every week, on the same day each time.

## What should you do every month?

| Monthly task | What it catches |

| Run all updates on staging first, then production | Plugin conflicts before visitors see them. |

| Remove unused plugins and themes | Code that still runs, or still has holes, though nobody uses it. |

| Review admin users and application passwords | Old staff, agency and test accounts. |

| Check broken links and 404s in the server log | Pages that moved without a redirect. |

| Run a speed check on key pages | A new plugin or script that slowed the site. |

| Restore one file or one post from backup | A backup you can no longer open or reach. |

Monthly tasks follow the same order as the studio’s WordPress update runbook: back up, update on a copy, check, then production.

For the update itself, follow a fixed order. Read the installed versions, take a backup and update a copy of the site first. Run the checks, then repeat on production with the same versions. If an update breaks the site, our guide to [fixing the WordPress critical error](/blog/wordpress-critical-error/) walks through the log, the fix and the rollback.

## What should you do every quarter?

| Quarterly task | What it catches |

| Full restore drill on a non-production copy, timed | Missing parts of the backup and how long recovery really takes. |

| Review the PHP version against PHP’s support dates | A version near end of life and plugins that will break on the next one. |

| Search the error log for deprecation notices | Code that will stop working after the next PHP upgrade. |

| Check domain renewal, DNS records and email sending | An expiring domain or a broken recovery email. |

| Update the plugin inventory and owners | Abandoned plugins with no release in a long time. |

| Rotate hosting, SFTP and database passwords | Credentials shared with people who no longer need them. |

Quarterly tasks are the ones that prove the weekly and monthly work is real.

Some faults are not WordPress at all. Redirect loops that grow the URL, for example, end in a server error; see our [414 Request-URI Too Large guide](/blog/what-is-414-request-uri-too-large-understanding-the-error/).

## Printable WordPress maintenance checklist

Print this page or copy the list into your task tool. Tick each line and write the date.

## Checklist

- ### Weekly

[ ] Last backup finished, size looks right. [ ] Site Health and PHP error log read. [ ] Security releases applied. [ ] Homepage, a form and checkout tested. [ ] Uptime and SSL expiry checked.

- ### Monthly

[ ] Backup taken before updates. [ ] Updates run on staging, checked, then on production. [ ] Unused plugins and themes removed. [ ] Admin users reviewed. [ ] 404s and broken links checked. [ ] Speed checked on key pages. [ ] One file or post restored from backup.

- ### Quarterly

[ ] Full restore drill on a copy, timed: ____ minutes. [ ] Counts, media and key URLs match the baseline. [ ] Root files present after restore. [ ] PHP version and deprecation notices reviewed. [ ] Domain, DNS and email checked. [ ] Plugin inventory updated. [ ] Passwords rotated.

- ### After every incident

[ ] Cause, fix and rollback written down. [ ] Checklist updated with what the incident taught you.

## Limits: what this guide does not cover

- Our drill used a 13-post site on WordPress Playground with SQLite. A site with years of media, a large WooCommerce database or a MySQL server will take far longer. The timings show the method, not a benchmark.

- We did not test host backup tools, backup plugins or WXR exports. Per the WordPress documentation, a WXR export from Tools, Export holds posts, pages, comments, custom fields, terms, menus and custom posts. Settings, plugins, themes and media files are not in it, so it is not a full backup.

- We did not run the MySQL commands; they come from the WP-CLI and MySQL documentation.

- Multisite, object caches and external services such as CDNs and mail providers need their own checks.

## Want this run for you?

Our care team can run these checks on a schedule, including timed restore drills, and report the results to you.

[Talk to our care team](/services/website-maintenance/)

[Explore website care](https://w3experts.com/services/website-maintenance/)

- [WordPress developer docs: WordPress backups](https://developer.wordpress.org/advanced-administration/security/backup/) — accessed 2026-11-11T00:00:00+00:00
- [WordPress developer docs: Backing up your database](https://developer.wordpress.org/advanced-administration/security/backup/database/) — accessed 2026-11-11T00:00:00+00:00
- [WP-CLI command reference: wp db export](https://developer.wordpress.org/cli/commands/db/export/) — accessed 2026-11-11T00:00:00+00:00
- [WordPress developer docs: Upgrading WordPress](https://developer.wordpress.org/advanced-administration/upgrade/upgrading/) — accessed 2026-11-11T00:00:00+00:00
- [WordPress documentation: Tools Export screen](https://wordpress.org/documentation/article/tools-export-screen/) — accessed 2026-11-11T00:00:00+00:00
- [PHP: Supported versions](https://www.php.net/supported-versions.php) — accessed 2026-11-11T00:00:00+00:00

Canonical: https://w3experts.com/blog/wordpress-maintenance-checklist/
