← All posts

Suspend WordPress Options Autoload

By · · Updated

WordPress keeps its settings, and the settings of most plugins, in the options table in the database. Each setting is one row with a name and a value. The table is named wp_options by default, or wp_<site id>_options for each site on a multisite network. You can see all of them at /wp-admin/options.php.

One query for many settings#

A single page can need dozens of settings. Asking the database for each one would mean dozens of queries. To avoid that, each row has an autoload field. On every page, WordPress loads all the rows set to autoload with one query, and keeps them together in one big list called alloptions.

An options table where five rows are set to autoload and one is not. One query on every page loads the five rows into the alloptions list. One of them, old_plugin_data, was left behind by a deleted plugin and is much bigger than the rest.
Every row set to autoload is loaded on every page, in one list

This makes WordPress faster, as long as the list stays small. The trouble is that the list is loaded on every single page, whether the page needs those settings or not.

Why alloptions grows too big#

Most plugins save their settings with get_option and update_option, and many set them to autoload. Without a persistent object cache, WordPress transients are saved in the options table too. Good plugins remove their data when they are uninstalled, and give their transients an expiry time. Not all plugins do, so the table fills up with old data that is still loaded on every page.

A large alloptions list causes three problems.

The ideal size is 1MB or less. Since WordPress 6.6, Site Health warns you when autoloaded options add up to more than 800KB, and a new option larger than 150KB is no longer autoloaded unless the plugin asks for it.

A common tip that does not work#

Some people suggest setting autoload to "no" on every option to make alloptions smaller. It does not work the way they expect. If WordPress finds no rows set to autoload, it loads every row in the table instead.

WordPress loads alloptions and checks whether any rows are set to autoload. If yes, it loads only those rows. If no, it loads every row in the table.
If no row is set to autoload, WordPress loads the whole table

This is the part of the WordPress wp_load_alloptions function that does it.

$alloptions_db = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options WHERE autoload IN ( '" . implode( "', '", esc_sql( wp_autoload_values_to_autoload() ) ) . "' )" );

if ( ! $alloptions_db ) {
    $alloptions_db = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options" );
}
$wpdb->suppress_errors( $suppress );

$alloptions = array();
foreach ( (array) $alloptions_db as $o ) {
    $alloptions[ $o->option_name ] = $o->option_value;
}
  1. WordPress loads the rows set to autoload. Since WordPress 6.6, these are the rows with an autoload value of yes, on, auto-on or auto.
  2. If no row is found, it loads every row in the table, whatever its autoload value.
  3. It then puts the rows into the $alloptions list.

So at least one row must stay set to autoload, and turning autoload off by hand for many rows can make things worse.

Our solution#

Docket Cache takes a different approach. It does not change anything in the database. Instead, it changes what is kept in the cached copy of alloptions.

With Suspend WP Options Autoload turned on, the cached alloptions keeps only the WordPress core options, about 100 of them, such as the site title, the site address and the date format. Options added by plugins are left out. When a page asks for one of them, it is loaded on its own and then kept in the cache like any other item. Pages that do not need it never load it.

With the setting off, the cached alloptions holds the WordPress core options and all plugin options, and the whole list loads on every page. With it on, alloptions holds only the core options, and each plugin option is its own cache item, loaded only on pages that ask for it.
Suspend WP Options Autoload, off and on

The result is a small alloptions list that loads quickly on every page, while plugin settings are still cached and only loaded where they are used.

Turning it on#

Suspend WP Options Autoload is off by default. Turn it on under Optimisations on the Docket Cache Configuration screen, or add this line to wp-config.php.

define( 'DOCKET_CACHE_WPOPTALOAD', true );

When you turn it on or off from the Configuration screen, Docket Cache clears the cached options, so the change applies straight away. See DOCKET_CACHE_WPOPTALOAD.