Why I Don’t Use WordPress Backup Plugins

I don’t use WordPress backup plugins.

I’ve certainly used them before, and there are plenty of good ones. UpdraftPlus, BackWPup, Duplicator, BlogVault and VaultPress all approach the problem in slightly different ways.

Karl carrying a WordPress database backup and file archive uphill towards a storage snapshot

If all I had was a WordPress site on somebody else’s hosting account, I’d happily use one. But when I control the server, I don’t see much reason to involve WordPress in its own backups.

WordPress is a pretty bad place to do this

A WordPress backup is mostly two things: files and a database. If I ask WordPress to back itself up, something eventually has to walk the filesystem, read all those files and get them somewhere else. Depending on the tool, that might involve PHP, an agent, SSH, incremental transfers or creating a big archive first. The database needs to go somewhere too.

This is perfectly reasonable when a backup service has no access to anything below the application. It has to work with what it’s got.

But if I have a 20 GB WordPress site sitting on storage that supports snapshots, reading and packaging 20 GB of files just to preserve their current state feels like doing the work at the wrong layer. The storage already has the data, so I’d rather let the storage deal with it.

This is how I’ve been doing backups

For sites where I control the server, my backups have generally lived outside WordPress. There’s nothing particularly clever about this. A simple version is a shell script using mysqldump for the database and tar for the files, followed by another copy somewhere off-site. I actually teach exactly this approach in WP Shell.

It isn’t instant and it isn’t especially sophisticated, but it has an important property: WordPress has absolutely nothing to do with it. The site can be broken, PHP can be completely dead, or I can replace WordPress with a directory containing a photograph of my cat and the backup script will quite happily back that up instead.

That’s how I want a backup system to behave.

Snapshots make this much more interesting

Once the underlying storage supports snapshots, I can do better than tar. A copy-on-write snapshot doesn’t need to make another complete copy of a 20 GB site before it can give me a restore point. The existing data can be shared until it starts changing.

That makes snapshots cheap enough to use as part of normal operations. I can take one before updating WordPress, before a plugin update, before a deployment, or before running a search-and-replace command that I’m fairly sure is correct.

None of this needs to know anything about WordPress, and that’s the part I find particularly attractive. The backup system sits below the thing it’s protecting.

Of course, a snapshot isn’t a backup

This distinction matters. If I take a snapshot on a server and the server dies along with its disks, my lovely snapshot has died with it.

Distributed storage helps with hardware failures, but the same principle applies. If both the live data and every snapshot are on the same Ceph cluster, I don’t want that to be my only copy of anything important.

I think of snapshots as cheap restore points. They’re useful for quickly going backwards after a bad deployment, update or accidental change, and they’re a useful starting point for making another copy without having to work from a moving filesystem.

A proper backup system still needs independent copies, retention, monitoring, failed-backup alerts and periodic restore tests. Ideally at least one copy should live somewhere that doesn’t share the same failure domain as the production storage.

The database is the awkward bit

WordPress files are relatively easy. MySQL deserves more care because I can’t just take an arbitrary storage snapshot while the database is busy and assume I’ve magically got a perfectly consistent database backup.

There are several ways to deal with this depending on how the database is running and what guarantees I need. That might mean a database dump, database-native backup tooling, coordinating a storage snapshot with MySQL, or briefly stopping writes.

I don’t think this weakens the argument for infrastructure-level backups. The hosting platform already knows where MySQL is, where the site’s files are and which database belongs to which site. It is in a much better position to coordinate the two than a plugin working from inside WordPress.

One site versus fifty

The difference becomes more obvious when you’re looking after client sites. I wrote about this more generally in What I Look for in WordPress Hosting for Agencies.

With one site, installing a backup plugin and configuring a schedule isn’t much work. With fifty sites, I now have fifty WordPress installations involved in their own backup process, fifty configurations to think about and fifty sites consuming resources to protect themselves.

A central management service can make the configuration part much nicer, but the actual work still has to happen somewhere. I’d much rather configure an infrastructure policy that says something like “back up every production site daily and keep 14 days.”

A new site gets the policy automatically. If WordPress stops working, nothing changes. If I delete the WordPress installation entirely, I’d still like to be able to restore yesterday’s version.

Restores are the real reason I care

Backups are only useful because eventually somebody needs to restore one. If a client calls because something broke ten minutes ago, I don’t particularly care that a backup dashboard has a reassuring green tick next to yesterday’s job. I care how quickly I can put the site back.

Downloading an archive, unpacking it, replacing files and importing a database works, but it’s a lot of moving parts for what should ideally be a fairly boring operation. If the infrastructure already has a snapshot from before the change, restoring the site can potentially be much simpler and faster.

I also don’t necessarily want to overwrite production. Sometimes I want to restore yesterday’s backup into another environment, inspect what happened, recover whatever I need and then throw that environment away. That becomes much easier when backups, storage and environments are all managed by the same system.

Backups should be part of the hosting platform

This is one of the things I’m working on for the WordPress hosting platform I mentioned in my previous post.

I’m experimenting with Ceph and dedicated servers, and there are still some decisions to make around database consistency and getting backups off the storage cluster. I don’t know exactly what the finished backup system will look like yet, but I do know that I don’t want WordPress involved.

If the platform controls the storage, database and compute, it already has everything it needs to take backups and restore them. There’s no reason to install another plugin on every site to do the same job from inside WordPress.

For WordPress sites on infrastructure I don’t control, backup plugins still make perfect sense. In fact, having a backup that’s independent of the hosting provider can be a very good thing.

But when I control the infrastructure underneath WordPress, I’d rather back it up from underneath it.