WordPress database optimization: autoload, revisions, and cruft
A WordPress database collects junk for years: post revisions, expired transients, settings from plugins you deleted in 2019. A bloated database makes every query a little slower, and some of that junk is read on every single page. The good news is that cleaning it up is mostly safe and mostly one-time. Start with the one that hurts most.
Here is what is worth your attention, in order.
Autoloaded options: the tax on every page
WordPress keeps site settings in the wp_options table, and the ones marked to autoload are read together in a single query on every request, logged in or out, cached or not. That is efficient when the data is small. It is a problem when a plugin parks hundreds of kilobytes of its own data in there and never cleans up, because now every page load drags that weight along.
So keep your autoloaded options small. WordPress 6.6 added a Site Health check and now skips autoloading very large options, flagging your site once autoloaded data crosses roughly 800KB. If you are over that, find the offending rows (Site Health will point you, or query the table sorted by length) and work out which plugin left them. This is the database issue most likely to quietly slow a whole site, and the one almost nobody checks.
Post revisions: unlimited by default
Every time you save a post, WordPress stores the previous version as a revision, and it keeps them all unless you say otherwise. A page that has been edited two hundred times is two hundred extra rows. Handy for recovering your work, wasteful once they pile up.
Cap them in wp-config.php:
define( 'WP_POST_REVISIONS', 5 );
That keeps the five most recent revisions per post and drops the older ones as you edit. You can set it to false to turn revisions off entirely, though keeping a handful is a sensible safety net. The revisions documentation has the details. Existing revisions stay until you clean them out, so a one-time sweep plus this constant is the full fix.
Transients and the rest of the cruft
Transients are cached values with an expiry date. Without a persistent object cache they live in the options table, and expired ones are not always cleaned up promptly, so they accumulate. Alongside them you collect spam and trashed comments, posts left in the trash, and orphaned metadata pointing at things that no longer exist.
None of these is a crisis on its own. Together, over years, they pad the database and slow the queries that scan those tables. A periodic sweep with a reputable optimization plugin, or a few careful SQL queries if you know what you are doing, clears them out. Back up the database first. Always back up the database first.
Do not over-optimize
A database cleanup is a tune-up, not a religion. Run it occasionally, keep autoloaded options in check, cap your revisions, and move on. Daily automated optimization of a small site is busywork that mostly just churns the tables.
On most sites the database is not the bottleneck; the server and the front end are. But on a large, old, plugin-heavy site, autoloaded bloat can be the thing nobody thought to look at. Right-size the effort to the site.
For where this fits in the whole picture, see how to actually speed up a WordPress site, and for the caching that keeps the database from being hit in the first place, WordPress caching explained.