Guide WordPress

How to clean up and optimise the WordPress database

What actually accumulates in a WordPress database over time, and how to clear it out safely before optimising the tables.

Updated 7 min read Intermediate

A WordPress database that has been running for a few years without any cleanup nearly always contains far more than the posts, pages and settings that are actually in use. Post revisions, expired transients, spam comments and trashed items all sit in the same tables as everything else, and none of them are removed automatically by default.

Back up the database before you touch any of this

Everything below involves deleting rows from a live database. See backing up a WordPress site first — a database backup takes moments and means none of the steps here carry any real risk.

What actually builds up

WhatWhy it accumulates
Post revisionsWordPress saves a full revision every time a post or page is saved, with no limit by default. A page edited fifty times has fifty stored copies sitting in the database indefinitely.
Auto-draftsLeft behind by the editor's autosave feature, including drafts nobody ever finished or published.
Trashed posts and commentsWordPress moves deleted items to trash rather than removing them, and by default only empties the trash automatically after 30 days.
Spam commentsHeld in the spam queue rather than deleted outright, which is useful for reviewing false positives but adds up on a site that gets consistent spam traffic.
Expired transientsTransients are temporary cached data with an expiry time. Plugins are supposed to clean up after themselves once a transient expires, and not all of them do.
Orphaned metadataRows in the postmeta or commentmeta tables left behind after the post or comment they belonged to was deleted through means that skipped WordPress's normal cleanup.

Method 1: WP-CLI, if you have SSH access

The fastest and most precise method, since each command targets exactly one type of clutter.

wp post delete $(wp post list --post_type='revision' --format=ids) --force
wp transient delete --expired
wp comment delete $(wp comment list --status=spam --format=ids) --force

Run each with the site backed up, and check the site afterwards. Deleting revisions in particular is irreversible — if you rely on being able to roll a specific page back to an earlier draft, confirm you do not need any of those revisions before removing them in bulk.

Once the clutter is removed, optimise the tables themselves to reclaim the disk space and rebuild index efficiency:

wp db optimize

Method 2: a database cleanup plugin

Without command-line access, a cleanup plugin does the same job from wp-admin, usually presenting each category — revisions, transients, spam, trash — as a separate item you can review and clear individually rather than all at once. This is a reasonable middle ground: less precise than WP-CLI, considerably less manual than doing it by hand in phpMyAdmin.

Limit future revisions instead of only clearing existing ones

Add this to wp-config.php to cap how many revisions WordPress keeps per post going forward, rather than accumulating indefinitely again:

define( 'WP_POST_REVISIONS', 5 );

Method 3: by hand in phpMyAdmin

Useful when you want to see exactly what is being removed before it happens. In phpMyAdmin, run a query like this to find revisions:

SELECT ID, post_title, post_date FROM wp_posts WHERE post_type = 'revision';

Review the result, then delete with the equivalent DELETE statement once you are confident. Working this way is slower but leaves nothing to guesswork, which matters if the database has custom tables from plugins that a generic cleanup tool would not know to leave alone.

Your table prefix might not be wp_

If a security precaution changed the default table prefix during installation, adjust the table names in any query accordingly. Check $table_prefix in wp-config.php if you are not sure what your site uses.

The autoloaded options problem

Separate from general clutter, some plugins store settings as "autoloaded" options — data pulled into memory automatically on every single page load, whether that page needs it or not. A plugin that stores a large amount of data this way, or one that was removed without cleaning up after itself, can measurably slow down every page on the site even though it never shows up as an obvious symptom. Checking the total size of autoloaded options is worth doing if a site feels generally sluggish after ruling out the more obvious causes — see why your WordPress site is slow.

After cleaning up

Running OPTIMIZE TABLE — or wp db optimize, which does the same thing — after removing a meaningful amount of data reclaims the disk space those deleted rows were using and can improve query performance on tables that had a lot of overhead. It is a quick step and worth doing every time, not just occasionally.

Set a repeat reminder for this rather than treating it as a one-off, and pair it with the other routine tasks in the monthly WordPress maintenance checklist.

Frequently asked questions

How often should I do this?

Quarterly is reasonable for most sites. A site publishing frequently with a lot of editing, or one running several plugins that make heavy use of transients, benefits from monthly cleanups. Either way, it belongs on the same kind of schedule as other routine maintenance rather than being a one-off.

Will this make my site noticeably faster?

It helps most on a site whose database has genuinely bloated — years of unlimited revisions, an old plugin's abandoned transients, thousands of spam comments. On a database that is already reasonably tidy, the gain is smaller. It is worth doing as routine hygiene either way, but it is not a substitute for caching or a look at what is genuinely slow — see why your WordPress site is slow.

Related reading