If your WordPress dashboard feels sluggish even after you've installed a caching plugin, checked PHP version, and confirmed the server itself isn't under load, the next place to look is the wp_options table. It's one of the quietest performance killers in WordPress because nothing visibly breaks — pages just get slower, admin-ajax calls take longer, and every single page load pays a tax you can't see in a screenshot.

Symptom: Everything Loads a Little Slower, For No Obvious Reason

Typical signs we see on tickets:

  • Time-to-first-byte (TTFB) creeps up over months without any traffic increase.
  • The site was fast right after migration or a fresh install, and has been getting slower ever since.
  • wp-admin feels heavier than the front end, especially the Dashboard and Plugins screens.
  • A database backup or export that used to take a minute now takes several.
  • phpMyAdmin shows wp_options as one of the largest tables in the database, sometimes bigger than wp_posts.

None of this throws an error. That's what makes it easy to miss — you're not chasing a 500 or a white screen, you're chasing a slow leak.

Cause: Autoloaded Data and Orphaned Transients

Every row in wp_options has an autoload column set to either yes or no. On every single page request — front end or admin — WordPress runs one query that pulls every row where autoload = 'yes' into memory before it even starts rendering anything. That's by design; it saves WordPress from running dozens of separate queries for commonly-needed settings like the site URL, active theme, and active plugins list.

The problem is that plugins are supposed to set autoload to no for anything that isn't needed on every request, and a lot of them don't. Over time you accumulate:

  • Transients set to autoload. Transients are meant to be temporary cached data with an expiry, but many plugins store them as regular autoloaded options. If the cron job that's supposed to clean them up stops running (common after a migration, since wp-cron depends on site visits), they just pile up.
  • Orphaned transients from deleted or deactivated plugins. Uninstalling a plugin rarely cleans up its options rows. We've seen sites carrying tens of thousands of leftover rows from page builders, SEO plugins, and import tools that were removed years ago.
  • Large serialized arrays. Some plugins (backup tools, security scanners, page builders) store big serialized PHP arrays as a single option — logs, scan results, revision history — and never trim them.
  • Duplicate rows from race conditions. High-traffic sites occasionally get duplicate option rows when two requests try to create the same transient at once, especially without an object cache to serialize the writes.

Individually these are small. Multiply by a few thousand rows and a few years of uptime, and it's not unusual to find an autoloaded payload of 5–20 MB being pulled into PHP memory on every request — before a single template file even loads.

Fix: Measure First, Then Clean Up

Don't start deleting rows blind. Measure the autoload size first so you know whether this is actually your bottleneck.

1. Check the autoload payload size

Run this in phpMyAdmin's SQL tab (Databases → your WordPress DB → SQL), or via terminal" class="auto-link">WP-CLI over SSH:

SELECT SUM(LENGTH(option_value))/1024/1024 AS autoload_mb
FROM wp_options
WHERE autoload = 'yes';

As a rough guide for what that number means:

Autoload sizeWhat it means
Under 1 MBHealthy, not your bottleneck
1–3 MBWorth a cleanup, not urgent
Over 3 MBLikely contributing to slow TTFB — clean it up
Over 10 MBSignificant issue, prioritize this fix

2. Find the worst offenders

SELECT option_name, LENGTH(option_value) AS size_bytes
FROM wp_options
WHERE autoload = 'yes'
ORDER BY size_bytes DESC
LIMIT 25;

Look at the option_name column. Anything starting with _transient_ or _site_transient_ should almost never be autoloaded — that's usually a plugin bug or a leftover from a plugin you no longer run. Note the plugin prefixes too (e.g. wpseo_, elementor_, wc_) so you know which plugin to check before deleting anything.

3. Clear expired transients safely

If you have WP-CLI (most SkyServer hosting and VPS plans do — check with wp --info over SSH), this is the safest route because it uses WordPress's own transient API rather than raw SQL:

wp transient delete --expired
wp transient delete --all

No WP-CLI? Use a maintenance plugin like WP-Optimize or Advanced Database Cleaner, which have a dedicated "clean transients" action. Avoid plugins that promise one-click "optimize everything" without letting you see what's being deleted first.

4. Manually remove orphaned rows (careful step)

Take a full database backup before this step — in cPanel, go to Backup → Download a MySQL Database Backup, or export via phpMyAdmin. Then, for transients that somehow survived the WP-CLI cleanup:

DELETE FROM wp_options
WHERE option_name LIKE '\_transient\_%'
AND option_name NOT LIKE '\_transient\_timeout\_%';

DELETE FROM wp_options
WHERE option_name LIKE '\_transient\_timeout\_%'
AND option_value < UNIX_TIMESTAMP();

Don't run a blanket DELETE on anything else without confirming the plugin it belongs to is actually gone. Options like siteurl, active_plugins, and theme mods are meant to stay autoloaded — deleting the wrong row can break login or take the site offline.

5. Fix autoload flags instead of deleting, where you can

Some rows are legitimate data you want to keep, just not on every request. If you're comfortable with SQL and know the option isn't read on every page load, you can flip its autoload flag instead of deleting it:

UPDATE wp_options SET autoload = 'no' WHERE option_name = 'example_plugin_log_data';

This keeps the data available but stops it from being pulled into every request.

Prevention: Keep It From Coming Back

  • Make sure real cron is running. If wp-cron relies on site visits (the default), low-traffic sites never trigger scheduled cleanup tasks. Disable DISABLE_WP_CRON in wp-config.php and add a real cron job in cPanel that hits wp-cron.php every 15 minutes, or use wp cron event run --due-now on a server cron.
  • Clean up after removing plugins. When you deactivate and delete a plugin, check wp_options for its leftover prefix and remove it manually if the plugin didn't clean up after itself.
  • Add an object cache. Redis or Memcached (available on SkyServer VPS plans) caches the autoloaded options in memory after the first load, so even a heavier table doesn't cost you a full MySQL round-trip on every request.
  • Check autoload size quarterly. Run the SQL query from Step 1 every few months on any site running more than 15–20 plugins. It takes ten seconds and tells you if something's trending in the wrong direction before it becomes a real problem.

Frequently Asked Questions

Will cleaning up wp_options actually make my site faster?

If your autoload size was over a few megabytes, yes — you'll usually see a measurable drop in TTFB because MySQL has less to read and PHP has less to unserialize on every request. If autoload was already under 1 MB, this specific fix won't move the needle much and you should look at caching, PHP version, or query performance instead.

Is it safe to delete all transients?

Yes. Transients are explicitly designed to be disposable cached data with an expiry — WordPress and plugins will simply regenerate them the next time they're needed. Deleting them can cause a brief slowdown right after cleanup as caches rebuild, but no data is permanently lost.

How do I know which plugin an option row belongs to?

Look at the prefix of the option_name. Most well-built plugins prefix their options with a plugin slug or abbreviation (wc_ for WooCommerce, wpseo_ for Yoast, etc.). If you're unsure, search the plugin's slug on wordpress.org or check its source in wp-content/plugins/ before deleting.

Can I just install a plugin to fix this automatically?

Cleanup plugins like WP-Optimize or Advanced Database Cleaner are fine for the transient-clearing step, but be cautious with any plugin that offers to bulk-delete "unused" options automatically — always review the list first. Automated tools can't always tell the difference between an orphaned row and one a rarely-used feature still needs.

Does this affect WooCommerce stores more than regular sites?

Generally yes. WooCommerce and its extensions are heavy users of transients for things like shipping rate caches, tax calculations, and reports, so stores with several WooCommerce extensions tend to accumulate autoloaded bloat faster than a basic blog. It's worth checking the autoload size more often on an active store.