Every WordPress page load begins with a single SQL query: SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes'. The result is loaded into memory and cached in the object cache as the alloptions group. Any subsequent call to get_option() for an autoloaded option reads from this in-memory cache — no additional database query needed. The problem is that plugins frequently register dozens of options with autoload = 'yes' (the default) even when those options are only needed on specific admin pages or rarely-visited front-end routes. On a mature site with many plugins, the autoloaded options dataset can grow to hundreds of kilobytes — inflating every page’s initial memory footprint and slowing the startup query. Auditing and correcting the autoload flag is one of the highest-impact, lowest-risk database optimizations available for WordPress sites.
Problem: Your site's initial wp_options autoload query returns 800KB of data on every page load, most of which belongs to plugin options that are only needed in the admin area or on a single page.
Solution: Audit which options are autoloaded and how large they are, then set autoload = 'no' on options that don't need to load on every request. Register your own options with autoload = 'no' from the start when they are admin-only or rarely needed.
<?php
// ── Audit: find the largest autoloaded options ─────────────────────────
function audit_autoloaded_options() {
global $wpdb;
return $wpdb->get_results(
"SELECT option_name, LENGTH(option_value) AS size_bytes
FROM {$wpdb->options}
WHERE autoload = 'yes'
ORDER BY size_bytes DESC
LIMIT 30"
);
}
// ── Total autoload size ────────────────────────────────────────────────
function get_total_autoload_size() {
global $wpdb;
return $wpdb->get_var(
"SELECT SUM(LENGTH(option_value))
FROM {$wpdb->options}
WHERE autoload = 'yes'"
);
}
// ── Disable autoload for a specific option ─────────────────────────────
function disable_option_autoload( $option_name ) {
global $wpdb;
return $wpdb->update(
$wpdb->options,
[ 'autoload' => 'no' ],
[ 'option_name' => $option_name ]
);
}
// ── Register your own options with autoload disabled ───────────────────
// Third parameter of add_option() controls autoload (default 'yes')
add_option( 'my_plugin_api_key', '', '', 'no' ); // admin-only, no need to autoload
add_option( 'my_plugin_cache_buster', '', '', 'no' );
// When updating an existing option that was previously autoloaded,
// use update_option() with the $autoload parameter (WP 4.2+):
update_option( 'my_plugin_settings', $value, false ); // false = autoload 'no'
Example audit output — identify candidates to disable:
<?php
// Run once in wp-admin or WP-CLI to see what to fix:
$results = audit_autoloaded_options();
foreach ( $results as $row ) {
printf( "%-60s %s bytes
",
$row->option_name,
number_format( $row->size_bytes )
);
}
echo "
Total autoload size: " . number_format( get_total_autoload_size() ) . " bytes
";
// Common large offenders: transient leftovers, Elementor CSS,
// WooCommerce product count caches, plugin update check data.
// Fix them:
$candidates = [
'_site_transient_update_plugins',
'_site_transient_update_themes',
'elementor_css',
'woocommerce_attribute_taxonomies',
];
foreach ( $candidates as $name ) {
disable_option_autoload( $name );
}
NOTE: Setting autoload = 'no' on an option does not delete or change its value — it only changes whether it is included in the startup batch load. Subsequent calls to get_option() for that option will issue an individual database query the first time per request (and be cached in the object cache for the remainder of the request). The right candidates to disable are options only needed in the admin, options used on a single page type, and transient-like data that plugins incorrectly store as options. Do not disable autoload for options used on every front-end request (e.g. siteurl, blogname, active_plugins) — this would cause a query flood.