Clean Bloated Autoload Options in WordPress with WP-CLI

by Fahim

A client site I migrated last week had an 880ms TTFB on static pages with zero server load. The culprit was a 6.2MB autoloaded blob in the wp_options table, dragged into memory on every single uncached request before WordPress could even start rendering a template.

We can audit the wp_options table over SSH, hunt down abandoned plugin junk, clear stale transients, and flip heavy data flags using WP-CLI on Hostinger. Running this cleanup dropped my client’s database execution time on requests from 412ms down to 14ms.

Terminal screen running WP-CLI commands to clean bloated autoloaded options in WordPress
Terminal screen running WP-CLI commands to clean bloated autoloaded options in WordPress

Why Bloated Autoload Options Destroy WordPress Performance

Every time WordPress spins up an uncached request, it fires a query: SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes' (or autoload = 'on' in WordPress 6.6+). This pulls global settings, active plugin states, theme customizer data, and rewrite rules straight into PHP memory.

Keep that payload under 800KB and MySQL retrieves it instantly from memory buffers. But when third-party plugins dump serialized arrays, debug logs, design tokens, and cart records into autoloaded rows, that payload swells to 5MB, 10MB, or more. If you’re running into migration bottlenecks like this, our guide on how to migrate a large WordPress site to Hostinger using SSH and WP-CLI walks through matching your environment variables.

Bloated autoload triggers two problems at once:

  • PHP Memory Exhaustion: If your autoload size is 5MB and 20 requests hit simultaneously, PHP-FPM consumes an extra 100MB of RAM just holding dormant strings it won’t even use.
  • Database Contention: MySQL struggles to keep huge single-row strings in memory buffers under concurrent writes, spiking disk I/O.

The WordPress Optimization documentation notes that anything over 1MB of autoload data needs immediate cleanup.

Accessing WP-CLI via SSH on Hostinger

First, get onto the server. In Hostinger’s hPanel, head to Advanced > SSH Access and make sure SSH is turned on. Grab your port, username, and server IP from that screen.

Drop into your terminal and connect:

ssh -p 65002 u123456789@195.35.40.12

Jump to your WordPress web root. On Hostinger, your public directory lives at domains/yourdomain.com/public_html.

cd domains/example.com/public_html
wp core version

If you see a version like 6.6.2, you’re good. Hostinger maps wp to the system PHP binary by default. If you run into weird routing or permission glitches, take a look at our guide on LiteSpeed .htaccess configurations on Hostinger.

Measuring Your Current Autoload Size

Don’t guess—check the actual footprint. We’ll run a quick SQL query through WP-CLI to sum the byte length of every row set to autoload.

Run this query:

wp db query "SELECT 'Autoload Size (MB)' AS Metric, ROUND(SUM(LENGTH(option_value)) / 1024 / 1024, 2) AS Size_MB FROM wp_options WHERE autoload IN ('yes', 'on');"

Here’s what I saw on the bloated client install:

+--------------------+---------+
| Metric | Size_MB |
+--------------------+---------+
| Autoload Size (MB) | 5.84 |
+--------------------+---------+

Anything above 1.0 MB is trouble. A tight, well-maintained WordPress install sits between 300KB and 700KB. At 5.84MB, PHP-FPM workers are wasting cycles just parsing strings before WordPress even touches the template hierarchy.

Querying and Identifying the Worst Offenders

Now pull the top 15 largest individual rows loaded on every hit, sorted by length descending.

Run this via WP-CLI:

wp db query "SELECT option_name, LENGTH(option_value) AS value_length, autoload FROM wp_options WHERE autoload IN ('yes', 'on') ORDER BY value_length DESC LIMIT 15;"

Look at the names in that output. The culprits almost always fall into these buckets:

  • Stuck Transients: Leftover rows named _transient_timeout_* or _transient_* that missed their expiration cleanup.
  • Ghost Plugins: Rows with prefixes from plugins removed months ago (like wpseo_*, elementor_*, or old form plugins).
  • Unchecked Logs: Security or sync plugins that wrote error traces directly into the database.
  • Bloated Rewrite Rules: Massive serialized lists in rewrite_rules caused by custom post types from deactivated plugins.

For more query parameters and syntax, refer to the WP-CLI Option command manual.

Safely Backing Up wp_options Before Pruning

Do not run destructive queries against production without a clean snapshot of the target table. Backing up the whole database is fine, but exporting just wp_options takes two seconds and gives you an instant rollback point.

Dump the table from your public_html directory:

wp db export wp_options_backup_$(date +%F_%T).sql --tables=wp_options

Confirm the dump exists and has data:

ls -lh wp_options_backup_*.sql

If you accidentally purge a row an active plugin needed, restore it immediately without affecting recent comments, orders, or posts:

wp db import wp_options_backup_YYYY-MM-DD_HH:MM:SS.sql

Deleting Abandoned Options and Transients with WP-CLI

Transients are meant to hold temporary cached data when an external object cache isn’t running. But many plugins write transients with autoload enabled. When their purge cron fails or the plugin gets deleted, those rows stick around permanently.

First, clear expired transients using WP-CLI’s native command:

wp transient delete --expired

Now check how many transients were written as regular options with autoload set to true:

wp db query "SELECT COUNT(*) FROM wp_options WHERE option_name LIKE '%_transient_%' AND autoload IN ('yes', 'on');"

If you see hundreds of rows, clear all transients across the board:

wp transient delete --all

Next, clean out remnants from uninstalled plugins. On my client’s site, a deleted tracker plugin left behind a 1.4MB row named tracker_event_cache.

Delete specific dead keys directly with WP-CLI:

wp option delete tracker_event_cache

If you find dozens of rows sharing a dead plugin’s prefix, remove them in bulk using SQL:

wp db query "DELETE FROM wp_options WHERE option_name LIKE 'oldplugin_%' AND autoload IN ('yes', 'on');"

Toggling Autoload to ‘no’ for Legitimate Heavy Data

Some plugins legitimately need their saved data, but they don’t need it on every anonymous page request. Think of form builders storing 400KB of lead logs or SEO audit caches that are only relevant inside /wp-admin/.

Don’t delete those rows—just toggle their autoload flag to no (or off).

Inspect the option first:

wp db query "SELECT option_name, autoload, LENGTH(option_value) FROM wp_options WHERE option_name = 'heavy_plugin_setting';"

Flip it so it only loads when the plugin explicitly calls get_option('heavy_plugin_setting'):

wp db query "UPDATE wp_options SET autoload = 'no' WHERE option_name = 'heavy_plugin_setting';"

On modern WordPress releases, you can also set the flag directly using WP-CLI:

wp db query "UPDATE wp_options SET autoload = 'off' WHERE option_name = 'heavy_plugin_setting';"

Once flipped, WordPress ignores this row during the front-end bootstrap. The plugin will still fetch it whenever it actually needs it, but normal site visitors stop paying the memory tax.

Gotchas: WordPress 6.6 Changes and Object Cache Invalidation

WordPress 6.6 changed how autoload values work under the hood. Per the WordPress Core 6.6 Autoload announcement, core now supports 'on', 'off', and 'auto' in addition to traditional 'yes' and 'no' values.

Keep these two traps in mind:

  1. Queries Missing Rows: If your audit queries filter strictly on WHERE autoload = 'yes', you’ll miss any options modified in 6.6+ that use 'on'. Always use autoload IN ('yes', 'on') in your SQL checks.
  2. Out-of-Sync Object Caches: If you run Redis, modifying rows with direct SQL via wp db query bypasses WordPress cache invalidation. Redis will keep serving the stale 5MB cached string until flushed.

Whenever you edit or delete options via SQL, flush your object cache right after:

wp cache flush

If you’re using LiteSpeed Cache on Hostinger, flush both the object cache and page cache:

wp litespeed-purge all

Finally, run an optimize query. MySQL does not automatically release disk space when you drop megabytes of table data due to index fragmentation. Reclaim it manually:

wp db query "OPTIMIZE TABLE wp_options;"

Now re-check your total autoload footprint:

wp db query "SELECT ROUND(SUM(LENGTH(option_value)) / 1024, 2) AS Size_KB FROM wp_options WHERE autoload IN ('yes', 'on');"

On my audit site, total autoload size dropped from 5,980KB to 418KB. Uncached request latency dropped by nearly 400ms immediately.

Frequently Asked Questions

What is the safe threshold for autoloaded options in WordPress?

Keep your total autoloaded size under 800KB. A clean install with a standard theme usually lives between 250KB and 450KB. Once you push past 1MB, database latency and memory usage start climbing under concurrent traffic.

Can I just delete any row that has a large option_value?

No. Some large options are essential, like active theme settings, WooCommerce tax matrices, or page builder CSS trees. Deleting them will break your site layout or checkout. If an active plugin needs the data, flip its autoload flag to 'no' or 'off' instead of deleting the row.

Why did my site break after updating options with wp db query?

You probably updated a serialized array using a query that broke PHP’s string length counts, or you deleted an option an active plugin requires during bootstrap. Always take a snapshot with wp db export --tables=wp_options before editing, and run wp cache flush right after any direct SQL edits.

Does Hostinger allow running WP-CLI commands on all plans?

Yes. Hostinger includes SSH and WP-CLI on all standard WordPress hosting plans, including Premium and Business. You just need to toggle SSH Access on inside hPanel to see your connection details.

Next Steps

Trimming bloated options gets rid of your PHP bootstrap bottleneck. To lock in those performance gains, back your database with an in-memory cache so remaining options are fetched directly from RAM instead of querying MySQL on every hit.

Check out our guide on how to configure Redis Object Cache in WordPress on Hostinger to cut your TTFB even further.

all_in_one_marketing_tool