Performance and monitoring
Optimise the wp_options table and "autoload" data
The wp_options table stores options for WordPress, plugins and themes. Some are loaded together as autoload to avoid repeated lookups. If that set grows too large, it can increase the work of reading, unserialising and memory, even if you use an object cache.
Each option is not necessarily queried separately or on every request to the server: WordPress reuses the alloptions set, and a page cache can avoid running WordPress altogether.
Measure without changing data
Confirm your installation's prefix. The examples use wp_options; on multisite you must identify the site and its corresponding table. From SQL in phpMyAdmin, calculate the number and bytes:
SELECT COUNT(*) AS opciones, COALESCE(SUM(OCTET_LENGTH(option_value)), 0) AS bytes, ROUND(COALESCE(SUM(OCTET_LENGTH(option_value)), 0) / 1024, 2) AS kib FROM wp_options WHERE autoload IN ('yes', 'on', 'auto-on', 'auto');
The query includes the values that current WordPress treats as autoloaded by default. An installation can filter them; see the autoload values function and how your version behaves.
Site Health may warn you if the set exceeds its threshold, which depends on the version and filters. No universal size guarantees a problem: relate the measurement to real memory and times.
Find large options
SELECT option_name, autoload, OCTET_LENGTH(option_value) AS bytes FROM wp_options WHERE autoload IN ('yes', 'on', 'auto-on', 'auto') ORDER BY OCTET_LENGTH(option_value) DESC LIMIT 20;
Start with the names and sizes. You do not need to export the full values to prioritise; they may contain credentials or user data.
Identify the plugin or theme responsible by searching for the exact name in its code and documentation. Deactivated does not mean abandoned: its data may be needed if it is reactivated. Test a clean-up or autoload change on a clone and with a recoverable backup, using the WordPress API or the component's own tool.
Do not edit serialised values or switch every option to no-autoload in bulk. You could break data or replace a single combined load with many individual queries.
Review the whole table
If autoload does not explain the size, repeat the query without the filter:
SELECT option_name, autoload, OCTET_LENGTH(option_value) AS bytes FROM wp_options ORDER BY OCTET_LENGTH(option_value) DESC LIMIT 20;
Value bytes do not include all the table and index space. The row counts a tool shows for InnoDB may be estimates; use COUNT(*) when you need an exact count, bearing in mind its cost on large tables.
Cron, transients and sessions
If the cron option grows, review the scheduled tasks and the component that adds them. Do not delete or edit its serialised structure. The WP-Cron guide explains how to change the trigger without stopping the tasks you need.
Transients have a maximum lifetime and can disappear earlier. Depending on the configuration, they are stored in tables or in a persistent cache; not all of them are deleted as soon as they reach their date. To inspect them without showing values:
wp transient list --fields=name,expiration
If you have validated the backup and need to remove the expired ones, use wp transient delete --expired. If they reappear excessively, fix the component that generates them.
Session rows depend on the plugin; they are not necessarily standard WordPress logins. A generic clean-up based on a name match can lose carts or work in progress. Use the retention and tool of the component responsible.
Indexes and Redis
WordPress already creates indexes on its tables. Before adding another, check the existing ones:
SHOW INDEX FROM wp_options;
Review the slow query's plan with EXPLAIN and test any index on a clone. Do not add a composite index just because the table is large: it also costs space and work on every write.
An object cache with Redis can reduce repeated reads, but it does not remove the need to review an oversized set of options. After each change, compare times, memory, configuration and tasks to check that the improvement has not changed how the site works.
You may also find useful
- Diagnose slow LEFT JOIN queries in WordPress Analyse slow taxonomy queries with LEFT JOIN, compare plans and alternatives on a copy and avoid unm...
- SQL queries to clean orphaned data and purge the WordPress database Clean orphaned data, revisions and transients in WordPress with verified queries, a recoverable back...
- Slow "SELECT SQL_CALC_FOUND_ROWS" SQL queries Diagnose slow WordPress queries with SQL_CALC_FOUND_ROWS, find where they come from and validate any...
- How to load the reCAPTCHA script with Contact Form 7 only where it is needed Assess the cost of reCAPTCHA in Contact Form 7 and limit where it loads only after identifying every...
Something wrong or out of date? Tell us and we will review it.