The Query That Runs on Every WordPress Page Load
Before WordPress does anything useful — before it loads your theme, runs your plugins, or renders a single pixel — it runs this query:
SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes'
This loads every autoloaded option into memory. It happens on every page load, every admin page, every AJAX request, every REST API call. There is no way to skip it.
On a fresh WordPress install, this returns maybe 200 rows totaling 100KB. That's fine.
On a 2-year-old site with 30+ plugins installed (and 15 later deleted), it returns 2,000+ rows totaling 3-8MB. That's a problem.
How It Gets Out of Control
When a plugin is installed, it typically creates options in wp_options with autoload = 'yes'. This is WordPress's way of saying "load this into memory early because it's needed on every request."
The problem:
Plugins are generous with autoload. Many plugins flag every option as autoload, even settings that are only used on one admin page.
Deleted plugins leave their data behind. When you deactivate and delete a plugin, WordPress removes the files but not the database rows. Every option that plugin created stays in wp_options with autoload still set to 'yes'.
Transients with no expiry. Some plugins store transient data in wp_options (when there's no object cache) and set autoload to 'yes'. If the transient never expires, it lives in autoload forever.
Serialized blobs. Some options store huge serialized arrays — entire plugin configurations, cached API responses, migration logs. One option can be 500KB.
How to Check Your Autoload Size
Run this in phpMyAdmin or via WP-CLI:
SELECT SUM(LENGTH(option_value)) as autoload_size
FROM wp_options
WHERE autoload = 'yes';
- Under 500KB: Healthy
- 500KB - 1MB: Getting heavy
- 1MB - 3MB: Noticeably slow
- Over 3MB: Your site is suffering
To find the biggest offenders:
SELECT option_name, LENGTH(option_value) as size
FROM wp_options
WHERE autoload = 'yes'
ORDER BY size DESC
LIMIT 20;
You'll typically find:
-
_site_transient_*entries — cached data that should have expired - Options from plugins you deleted months ago
- Serialized arrays with thousands of entries
- Widget configurations from themes you no longer use
The Fix
Step 1: Identify What's Actually Needed
Core WordPress options need autoload. Your active theme's options need autoload. Your active plugins' critical settings need autoload.
Everything else? Probably doesn't.
Step 2: Disable Autoload for Orphaned Options
UPDATE wp_options SET autoload = 'no'
WHERE option_name LIKE 'deleted_plugin_prefix_%';
Be careful — changing autoload on active plugin options can break things. Only target options from plugins that are no longer installed.
Step 3: Delete Expired Transients
DELETE FROM wp_options
WHERE option_name LIKE '_transient_timeout_%'
AND option_value < UNIX_TIMESTAMP();
Then delete the corresponding transient data:
DELETE FROM wp_options
WHERE option_name LIKE '_transient_%'
AND option_name NOT LIKE '_transient_timeout_%'
AND option_name NOT IN (
SELECT REPLACE(option_name, '_transient_timeout_', '_transient_')
FROM wp_options
WHERE option_name LIKE '_transient_timeout_%'
AND option_value > UNIX_TIMESTAMP()
);
Step 4: Monitor Going Forward
After cleanup, check your autoload size monthly. Every time you remove a plugin, audit what it left behind.
Or Skip the Manual Work
This is exactly the kind of tedious, repeatable task that should be automated. WP Multitool's Autoload Optimizer shows you every autoloaded option, sorted by size, with the plugin it belongs to (if detectable). Toggle autoload on/off with one click. The Database Optimizer handles transient cleanup and orphaned data removal.
One plugin instead of running SQL queries by hand. $50 lifetime, and the autoload module alone can shave 500ms+ off every page load on a bloated site.
Originally published at WP Multitool Blog.
Find what's slowing your WordPress. WP Multitool — 14 modules, $50 lifetime, zero bloat. Built by Marcin Dudek.
Top comments (0)