Blog · Guides

Post Revisions: Keep the Safety Net, Lose the Database Bloat

Every time you save a draft or update a published post, WordPress quietly stores a copy of the previous version in the wp_posts table. That’s a revision, and it’s one of the most underrated safety features in WordPress. It’s also one of the most common sources of database bloat on sites that have been running for a few years. The fix isn’t to turn revisions off. It’s to give them sensible limits and clean up the ones you no longer need.

What Revisions Actually Do

A revision is a full snapshot of a post’s content, title, and excerpt at a point in time. WordPress creates one on every save, and a separate autosave every so often while you’re actively editing. This is what lets you open the revisions screen and roll back to something you wrote an hour ago, or recover content after a plugin conflict mangles a post, or figure out what a client actually approved before someone “improved” it.

None of that is optional in any meaningful sense. If you strip revisions out entirely, you lose the undo history for every post on your site, and the first time someone needs it, it won’t be there.

The Bloat Problem

The trouble is that WordPress, by default, keeps every revision forever. A post that’s been edited fifty times over three years carries fifty rows of near-duplicate content in the database. Multiply that across hundreds of posts and pages, and you can end up with a wp_posts table where revisions outnumber actual content by a wide margin.

This matters more than it looks like it should. A bloated posts table means slower queries, slower backups (because there’s simply more data to read and write), and a heavier database file sitting on your NVMe storage doing nothing but taking up space. On sites using persistent object caching with Redis, a lot of this gets masked for logged-out visitors, but it still shows up in admin screens, in backup times, and in database maintenance tasks.

Setting a Sensible Limit

The cleanest fix is to cap how many revisions WordPress keeps per post going forward. Add this to wp-config.php, above the line that says /* That's all, stop editing! */:

define( 'WP_POST_REVISIONS', 5 );

This tells WordPress to keep the five most recent revisions per post and automatically discard older ones as new ones are created. Five is a reasonable default for most sites: enough to recover from a bad edit or two, not enough to accumulate years of dead weight. If you run a content-heavy site where editors go back and forth a lot before publishing, you might push that to 10. If you rarely edit after publishing, 3 is plenty.

You can also space out autosaves, which reduces how many revisions get created in the first place during a single editing session:

define( 'AUTOSAVE_INTERVAL', 160 ); // seconds

The default is 60 seconds. Stretching it to two or three minutes cuts down on autosave noise without meaningfully increasing your risk if the browser crashes.

If you want to disable revisions entirely (not generally recommended, but sometimes appropriate for a site with no editorial workflow at all), the constant is:

define( 'WP_POST_REVISIONS', false );

Cleaning Up Existing Revisions with WP-CLI

Setting WP_POST_REVISIONS only controls what happens going forward. It does nothing about the revisions already sitting in your database from before you added the constant. For that, wp-cli is the right tool.

First, see what you’re dealing with:

wp post list --post_type=revision --format=count

If that number is in the thousands on a site that’s been around a while, don’t be surprised. Next, delete revisions older than a cutoff you’re comfortable with, rather than wiping everything at once. This example removes revisions attached to posts last modified more than a year ago:

wp post list --post_type=revision --post_status=inherit \
 --date_query='[{"before":"1 year ago"}]' --format=ids | \
 xargs -n 20 wp post delete --force

Piping to xargs -n 20 deletes in batches instead of passing thousands of IDs to a single command, which is gentler on the database and easier to interrupt if something looks wrong. Run the wp post list portion by itself first to confirm the IDs look right before adding the delete step.

Once you’ve cleaned up the backlog, run a database optimization pass so the freed space is actually reclaimed rather than just marked as available:

wp db optimize

If you’d rather work through a UI, plugins like WP-Optimize offer a revisions cleanup screen with similar batching logic. The wp-cli approach just gives you more control over the cutoff date and lets you script it as a recurring maintenance task.

Why Deleting Them All Is a Mistake

It’s tempting to run one broad command and wipe every revision on the site in one pass. Resist that. A few reasons:

  • You lose recent recovery options. The whole point of revisions is having something to roll back to. Deleting the last few revisions on actively edited posts removes the exact safety net you’re trying to preserve.
  • Recently edited content is the highest-value content to protect. Old, untouched posts rarely need their revision history. Posts someone edited yesterday are precisely where a rollback is most likely to get used.
  • A single mass delete on a large table can be a heavy, locking operation. Batching in smaller chunks, as shown above, avoids long lock times on busy sites.

The better mental model is: cap future growth with WP_POST_REVISIONS, and periodically prune old revisions past a reasonable age, rather than treating cleanup as a one-time nuke.

A Sane Maintenance Routine

Put together, a reasonable approach looks like this:

  1. Set WP_POST_REVISIONS to a number between 3 and 10 depending on your editorial workflow.
  2. Run a one-time cleanup of revisions older than 6 to 12 months using wp-cli, in batches.
  3. Follow up with wp db optimize to reclaim the space.
  4. Repeat the cleanup step every few months, or automate it as a scheduled task if your host supports cron jobs.

This keeps the safety net intact for anything recent while preventing the table from growing without bound. On managed environments like ServerBorn, routine database housekeeping and backups are already handled at the platform level, but the revision limit itself is a WordPress-level setting worth configuring deliberately rather than leaving to chance.

Takeaway

Revisions are worth keeping. Unlimited revisions are not. A sensible cap in wp-config.php plus an occasional wp-cli cleanup of old entries gives you the same recovery protection with a fraction of the database weight, and it takes about five minutes to set up.