An incremental backup copies only what changed since the last run, which is why it is fast and cheap. It is also why it can fail in ways a full backup never does. If you manage a few dozen client sites, it is worth knowing exactly what is in your backup chain before the day you need to restore from it.

What "incremental" actually means

A full backup copies everything: every file in wp-content, plus a dump of the database. An incremental backup copies the difference between now and some earlier point. Most tools work in one of two ways.

The first is a chain. Backup 1 is a full copy. Backup 2 holds only what changed since backup 1. Backup 3 holds only what changed since backup 2. To restore backup 3 you need 1, 2 and 3, applied in order.

The second is a snapshot model with deduplication. Every backup looks like a full copy to you, but under the hood files are split into chunks, each chunk is stored once, and a new backup only uploads chunks the storage has not seen. Restoring one snapshot does not depend on a chain of earlier ones, although it still depends on every chunk it references continuing to exist.

Ask your tool which model it uses. The failure modes differ, and so does what you can safely delete.

What gets copied for files

For files, the tool has to decide what "changed" means. The cheapest check is modified time and size. It is fast and correct nearly all of the time, but a file that changes without its size or timestamp changing gets missed, which is rare and real with deployment scripts that preserve timestamps. A content hash is reliable, but it means reading every file on every run, which costs disk I/O on cheap shared hosting. Most tools combine one of these with a file list diff to catch new and deleted files.

On a typical WordPress site the uploads folder is the bulk of the bytes and barely changes. Themes and plugins change in bursts, when you update. That is the ideal shape for incremental backups: a site with 12 GB of media and 40 MB of daily change should move roughly 40 MB a night, not 12 GB.

Check the arithmetic on your own portfolio. Fifty sites at 5 GB each is 250 GB per full run. If you ran fulls nightly to offsite storage you would push about 7.5 TB a month. Incrementals with a weekly full would move something closer to 250 GB times four, plus the daily deltas. That gap is the whole reason incrementals exist.

What gets copied for the database

Here is the part people assume works like files, and usually does not. A database is one logical thing. Most WordPress backup tools take a full mysqldump-style export of it on every run, even in an "incremental" backup, because diffing rows reliably is hard and the database is usually small.

That is fine until it is not. A WooCommerce store with a few million rows in wp_postmeta, or a site with heavy logging tables, can produce a database dump bigger than everything else combined. So your "incremental" backup may be mostly a full database dump; check the size of each run, not just the marketing page. And a file backup and a database dump taken minutes apart can disagree: an order placed between them exists in the database but its invoice PDF is not in the files, or the reverse. For a brochure site this does not matter. For a store it can.

Some tools use binary log or row-level change tracking to make database increments truly incremental. That is more powerful and more fragile. If you use it, test restores more often.

What can go wrong

Roughly in order of how often they bite:

  • A broken link in the chain. One incremental is corrupt or was pruned by a retention rule, and every later backup that depends on it is unrestorable, while the dashboard still shows green.
  • Retention that deletes the base. You keep "the last 14 backups" but the full they depend on is 15 days old and got removed. Good tools protect the base. Verify yours does.
  • Silent partial uploads. A timeout or an exhausted quota on the storage side leaves a truncated file. The job reports success because the local step finished.
  • Excluded paths nobody remembers. Someone excluded wp-content/cache years ago, and the exclusion pattern also matches a plugin's data directory.
  • Files that change during the read. A large export written while the backup runs gets copied half done.
  • Restore that needs more space than the host has. You cannot restore a 20 GB chain into a 10 GB plan.

Notice that none of these show up as a failed backup. They show up as a failed restore, which is the worst possible moment to find out.

How to check a chain without a disaster

You do not need a ritual. You need a small, repeatable test.

  1. Pick a site at random each month and restore its latest backup to a staging copy, not the live site.
  2. Compare the file count and total size against the live site. A few percent of difference from caches is normal. A missing directory is not.
  3. Load the site, log in, and open a post that has an image. Check that the media library loads.
  4. Note how long it took. That number is what you tell a client when they ask how long they would be down.

Then, once a quarter, restore from the oldest backup you still retain, not the newest. The newest is the one everyone tests. The oldest is where a pruned base shows up.

If you want a fuller argument for keeping copies in storage you control, we wrote about it in where should WordPress backups live.

Where this leaves you

Incremental backups are the right default for a portfolio of client sites, but "incremental" is a mechanism, not a guarantee. Know whether your tool uses a chain or deduplicated snapshots, know what it does with the database, and restore a random site every month. WPClientHub keeps backups on the client's server and can also copy them to your own offsite storage, and it takes a restore point before updates, so you get both a routine backup and a known-good rollback. WPClientHub is free for 3 sites if you want to try this on a real client site: start here.