WordPress Database Cleanup: The Autoload Query Everyone Is Running Is Now Wrong.

WordPress 7.1 stores autoload as on, off, auto or no. Every tutorial queries for yes, which now matches nothing and looks like a clean database.

Aditya Sharma·6 min read

Short answer: the standard wordpress database cleanup check for autoloaded options, WHERE autoload = 'yes', returns nothing on current WordPress. The column now holds on, off, auto and the legacy no. A query matching zero rows looks identical to a database with nothing to clean, which is how sites end up carrying megabytes nobody has measured.

I found this by running the check on a stock install and getting NULL.

The values actually in the column

Table of distinct autoload values on a WordPress 7.1 install. on has 213 rows totalling 66 KB, auto has 84 rows, off has 136, no is present as a legacy value, and yes has zero rows
Four values in use, and yes is not one of them on a fresh install. Sites upgraded from

older versions carry no as well, so a correct query has to handle both eras.*

ValueRowsMeaning
on213 (66.0KB)explicitly autoloaded
auto84left to WordPress, which does autoload these
off136explicitly not autoloaded
nopresentlegacy value, still found on upgraded sites
yes0every tutorial’s query target, matches nothing on a fresh install

Caveat: one install, WordPress 7.1. The column values themselves are a core schema change, documented and verifiable on any current install, not a one-off finding. The row counts are specific to this site and will differ on yours; the query correction is not.

Two of those values mean autoloaded. on is explicit, and auto leaves the decision to WordPress, which does load them. So a real measurement matches on, auto and legacy yes together.

Two SQL queries compared. The classic query filtering on autoload equals yes returns NULL. The corrected query filtering on on, auto and yes returns 297 rows totalling 66 KB, followed by a query listing the ten largest autoloaded options
If you have ever run an autoload audit on a client site and been pleasantly surprised,

run it again with the corrected clause. Matching nothing looks exactly like nothing to fix.*

Why autoload is the number that matters

Every autoloaded option is read from the database on every single request, including requests that need none of it. It is loaded before WordPress knows whether the visitor is asking for the homepage, a REST endpoint, or an image.

Table of the eight largest autoloaded options on a near-empty install: a core block CSS transient at 23.22 KB, rewrite_rules at 17.65 KB, a block styles transient at 11.08 KB, wp_user_roles at 7.94 KB, the cron array at 3.79 KB, and three smaller plugin rows
66 KB on a site with fifteen posts and four plugins, which is completely fine. The

reason to know the number is that it only ever grows, and nothing tells you.*

Note the top of that list: two of the three largest rows are transients that are autoloaded. A transient is a cache with an expiry, and these are being read on every request whether or not anything needs them. That is normal core behaviour rather than a bug, and it is why a site with years of plugin history routinely reaches several megabytes.

The cron row is worth a glance too. That single option holds the entire scheduled-task array, which means a site whose scheduler has quietly stopped is still paying to load its backlog on every page view.

The tables that actually grow

Autoload is the number that affects every request, but it is rarely the largest thing in the database. Four tables do most of the growing on a long-lived site.

wp_postmeta is almost always the biggest. Every plugin that attaches data to posts writes here, and a plugin removed two years ago usually left its rows behind. Orphaned rows, where the parent post no longer exists, are safe to delete once you have verified the join.

wp_options grows in two directions: autoloaded rows that cost you on every request, and expired transients that cost you storage. Both are worth clearing, for different reasons.

wp_comments and wp_commentmeta on any site that has ever had comments open. Spam that was caught and never emptied sits there indefinitely.

Plugin tables. Form submissions, order line items, activity logs, licence checks. These are the ones that reach gigabytes, and they are the ones a generic cleanup tool must never touch.

Measure before assuming:

SELECT table_name,
       ROUND((data_length + index_length)/1024/1024, 1) AS mb,
       table_rows
FROM information_schema.tables
WHERE table_schema = DATABASE()
ORDER BY (data_length + index_length) DESC
LIMIT 12;

That query tells you where the size actually is, which is frequently not where you expected.

What is safe to remove

Table of cleanup targets by safety. Expired transients, auto-drafts, trashed posts, spam comments and orphaned postmeta are safe. Post revisions and autoloaded options from removed plugins need checking first. Plugin-owned tables are never safe to guess at
The bottom row is where real damage happens. A generic cleanup tool offering to empty

tables it does not recognise is offering to delete a client’s orders.*

TargetSafe?Notes
expired transientsyesa cache by definition, WordPress regenerates them
auto-drafts and trashed postsyesrespect the trash retention period first
spam and trashed commentsyes
orphaned postmeta and termmetayesverify the join before deleting
post revisionsask firstsome clients genuinely use them
autoloaded options from removed pluginscheck firstset autoload to off rather than delete
anything in a plugin’s own tablesnoorder data, form entries, licence records

Two judgement calls worth making deliberately.

Revisions. Purging them is the default advice and it is wrong for some clients. Editors who actually use revisions will notice. Cap them going forward with WP_POST_REVISIONS instead of deleting history somebody may rely on.

Options from removed plugins. Set autoload to off rather than deleting the row. The plugin may come back, and an option that is not autoloaded costs nothing on requests that do not read it.

Running a WordPress database cleanup without breaking anything

The order matters more than the technique.

Take a backup and prove it restores. Not take one. Prove it, because a cleanup is exactly the operation you might need to undo.

Measure before. Record the autoload total and the ten largest rows. Without a before number you cannot tell a client what changed.

Change one category at a time. Transients, then trash, then orphaned meta. If something breaks you want to know which step did it.

Measure after, and load the site. Homepage, a form, the checkout if there is one.

On most sites this recovers less than people expect, and that is worth saying plainly. Database cleanup is not usually the reason a site is slow. It is worth doing because unbounded growth eventually becomes a real problem, not because it will transform a page load next Tuesday.

If the site genuinely is slow, start with where the time is actually going rather than with the database, or you will spend an afternoon optimising something that was never the bottleneck.

Protuno’s Performance agent, Dash, carries a database cleanup playbook that measures before and after and runs behind a proven restore point. Straight with you as on every post here: Dash is built and named but not live yet.

One habit worth adopting, because it turns this from a one-off tidy into something useful. Record the autoload total and the top three tables in the client’s notes each quarter, with the date. Four numbers, thirty seconds. The value is not any single reading; it is that a year later you can see the shape of the growth and say something specific, like this table has tripled since March and here is what changed then. Nobody can act on “the database is quite big”. Everybody can act on a trend with a date attached.

Run the corrected autoload query on your largest client site today. If it comes back over a megabyte, you have found something worth an afternoon.

Comments