WordPress Backups: What to Back Up, How Often, and How to Test a Restore

WordPress Backups: What to Back Up, How Often, and How to Test a Restore

Written by

in

Back up two things: the database and wp-content. Everything else on a WordPress install can be downloaded again. Back up daily if the site changes daily, keep at least one copy off the hosting account, and test a restore on a copy before you actually need one — an untested backup is a guess, not a backup.

I learned this the boring way. The one time a fix took a full day instead of ten minutes, the backup existed — it just would not restore, because nobody had ever opened it.

The short version

  • Database first. Posts, pages, users, settings, plugin options, menus and widget assignments all live there.
  • wp-content second. Uploads, themes, plugins, mu-plugins. Custom code lives here and cannot be re-downloaded.
  • Frequency follows how much work you would redo — not a number someone told you.
  • One copy must live off the server. A snapshot inside the same hosting account dies with the account.
  • Schedule a restore drill. Quarterly is enough for a small site, and it takes about twenty minutes on a copy.

What actually needs to be in the backup

The database is small and changes constantly; the files are large and change rarely. Treat them separately, because that difference decides your schedule and your storage bill.

In the database, the tables that matter are wp_posts (posts, pages, revisions, and the rows that define menus), wp_postmeta (custom fields — page builders store their entire layout here, so a database-only restore brings the layout back but not the images it points to), wp_users and wp_usermeta (logins and capabilities), wp_options (site URL, active plugins, cron schedule, theme settings), and the term tables that hold categories and tags. Plugin tables use their own prefixes and are easy to forget — a shop’s orders may sit in tables a “posts only” export never touches.

In the files, wp-content/uploads is usually the bulk of it, and it is also the part people most often exclude by accident. wp-content/themes and wp-content/plugins can mostly be re-downloaded, except for the child theme you edited and the plugin you patched by hand — those are original work and belong in the backup. wp-content/mu-plugins must always be included; it loads automatically, which is exactly why malware likes to hide there. I covered that pattern in the five-minute infection check.

Two files outside wp-content are worth the extra ten seconds: wp-config.php (database name, user, password, table prefix, and the security salts — losing the salts logs every user out) and .htaccess (redirects and caching rules that a plugin or your host wrote for you). The wp-config constants are covered in the seven settings I change on every new site.

Item Where it lives How often
Database MySQL, all tables with the site prefix Daily, and always before an update
wp-content/uploads Filesystem Weekly, or after adding a batch of media
Themes and plugins wp-content/themes, wp-content/plugins Before every update, plus weekly
mu-plugins wp-content/mu-plugins Always, with the file backup
Config and rewrite rules wp-config.php, .htaccess Every full backup
Core files, caches, old archives wp-admin, wp-includes, wp-content/cache Never — reinstall instead

How often you should back up

Ask one question: if the site died right now, how much work would I be willing to redo? That answer is your interval. A blog that publishes twice a week does not need a database dump every hour, but it does need one before every plugin update, because that is when things actually break.

My default for a small site:

  • Database: daily. It is small — usually a few megabytes — so there is no reason to be stingy.
  • Files: weekly, plus a manual snapshot whenever I install something new or edit a theme file.
  • Before anything risky: a manual backup with a name I will recognise, like before-woo-9-update. Updates, migrations, search-replace operations and malware cleanup all qualify.

Retention matters as much as frequency. I keep a rolling window — daily for a week, weekly for a month, one monthly kept a year — because some damage is silent. A hacked file can sit unnoticed for weeks, and by then every recent backup already contains it.

A hosting-provider snapshot is not the same as your own backup. Snapshots are fast and I use them, but they live in the same account — if the account is suspended or deleted, the snapshot goes with it. In my hacked-site recovery, the host’s copy was useful but not sufficient.

Where the backup should live

Keep three copies, on two different kinds of storage, with one of them off-site. That is the whole rule; everything else is detail.

Practically: one copy on the server for fast restores, one on your own machine, one in cloud storage you control. If the backup holds user data, encrypt it — a dump with email addresses and password hashes does not belong in a public bucket.

Two places a backup must never live: inside wp-content (a hack cleanup or a careless migration deletes that folder, and some server configurations will happily serve the archive to anyone who guesses the filename), and only in the same hosting account you are trying to protect yourself from.

There is also a boring test that catches more problems than any checklist: download a backup and open it. If pulling the file takes hours or the archive refuses to open, you do not have a backup. You have a file with a hopeful name.

Taking a backup you can actually restore

On shared hosting, use the host’s own backup tool first — it knows where the database is and it produces an archive you can download in one click. Then keep a second, independent copy through a plugin that ships to remote storage, or by hand if you have SSH access.

If you have WP-CLI, the whole job is three commands:

# 1) Database — dump every table, with DROP statements so it can overwrite cleanly
wp db export ~/backups/db-$(date +%F).sql --add-drop-table

# 2) Files — wp-content plus config, skipping caches and old archives
tar -czf ~/backups/files-$(date +%F).tar.gz \
  --exclude='wp-content/cache' \
  --exclude='wp-content/updraft' \
  --exclude='wp-content/ai1wm-backups' \
  wp-content wp-config.php .htaccess

# 3) Pull both copies off the server
scp user@host:~/backups/*-$(date +%F).* ./backups/

Without SSH, the same result comes from cPanel’s Backup tool plus phpMyAdmin: export the database with the “Add DROP TABLE” option enabled, then zip wp-content in File Manager. It is slower, but it works, and slow beats absent.

Whatever route you take, check the excludes. The most common silent failure I have seen is a backup job that skipped wp-content/uploads to save space, so the restore brought back every post with a broken image. Back up uploads separately at a lower frequency instead.

Test the restore, not just the backup

A backup is only proven when it has been restored once. Do it on a copy — a subdomain, a spare folder, or a local install — never on the live site. Twenty minutes, once a quarter:

  1. Create a clean target. New database, new directory, nothing shared with production.
  2. Import the database dump and unpack the files into the new directory.
  3. Point wp-config.php at the new database. If the domain differs, update the siteurl and home rows in wp_options, then run a serialised-safe search-replace so internal links stop pointing at the live domain. Do not do this with a plain text editor on a dump — serialised data breaks silently.
  4. Open the site and log in. Check the homepage, one post with images, the media library, permalinks (resave them if 404s appear), and the one plugin the business depends on.
  5. Write down the date and anything you had to fix. If the restore failed, you have just found out at the cheapest possible moment.

That drill is also how you discover that your backup excludes were wrong, your archive was truncated, or your plugin’s remote storage credentials expired months ago.

The checklist I actually use

  • Database dumped daily, with DROP statements, all prefixed tables included.
  • wp-content archived weekly, uploads and mu-plugins included.
  • wp-config.php and .htaccess saved alongside it.
  • No backup archives stored inside wp-content.
  • At least one copy off the hosting account, encrypted if it holds user data.
  • A manual snapshot before every update, migration or cleanup, with a dated name.
  • A restore tested on a copy this quarter, with the result written down.

The next time you touch this site, take one manual backup first and time how long the download takes. If it is slower than you expected, or the archive will not open, you have found your real problem before it found you.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *