KakapoWPKakapoWP
Log inTry for free
Help Center/Performance/Autoload: measure the options loaded on every request and switch them

Autoload: measure the options loaded on every request and switch them

Applies to: Kakapo Performance·4 min read

What is actually measured here

On every single request — home page, image, REST call — WordPress reads all options with the autoload column set, in one single query. So these rows do not cost time once, but always. Which values of the column count as “is loaded” is something Kakapo asks WordPress itself (wp_autoload_values_to_autoload, since 6.6, including its filter); on older installations the list yes, on, auto-on, auto applies. The length of each value is then counted in PHP, that is, real bytes. LENGTH() in SQL would be faster, but depending on the driver it counts characters instead of bytes — under SQLite that would put wrong numbers in the interface for umlauts and emoji. Reading happens in steps of 100 rows and at most 20,000 rows per run; if this cap is reached, the interface says so and explicitly marks the figures as a lower bound. The measurement only runs when you open the area or click “Measure again” — never while a visitor's page is being built — and is then valid for 300 seconds.

Reading the four key figures correctly

At the top there are four figures. “Loaded on every request” gives the total size, the number of options and the duration of the measurement. “Share of the warning threshold” calculates that against 800,000 bytes — exactly the same threshold as the WordPress core's “Site Health” check, including its filter; two different warning limits in one installation would only be confusing. “Of that, switchable” is the part without an active owner, that is, what you can actually touch. “Already switched over” adds up what you have already taken out of the loading process here. Below that, the “Where the load comes from” card shows the same amount broken down by origin, and the second card shows the 25 largest individual items.

The attribution is a name comparison, not proof

The options table has no “owner” column. Kakapo therefore compares the option name with what is actually on disk: directory name, file name of the main script and text domain of every installed plugin, as well as the slugs of all themes. The longest matching prefix wins, otherwise “kakapowp” would win over “kakapowp_performance” and the wrong plugin would be named. What a plugin really uses for its options is not stated in any header — an abbreviation such as “wpseo” cannot be derived from “Yoast SEO”. Such cases end up in the “no match” bucket, and that means “I don’t know”, not “belongs to nobody”. If you know a prefix for certain, you add it via the filter kwpp_autoload_praefixe; the plugin does exactly the same for its own prefix.

What can be switched over — and why a lot stays locked

The “Switch over” button only appears when two conditions are met at once: the option is at least 1 KB in size and it belongs to no active component. That keeps options of the WordPress core locked (a fixed list from populate_options plus the patterns theme_mods_*, widget_* and *_user_roles — those really are needed on every request), caches (transients belong in the deep cleanup, where they disappear entirely instead of merely being loaded later), everything belonging to an active plugin or to the active theme, and everything under 1 KB, because there the extra individual query costs more than the bytes saved. Hover the mouse over a greyed-out button: the reason is shown as a hint on it. The worthwhile case is almost always the inactive or long-since-uninstalled extension whose rows have simply been left lying around. Without a valid license the area is dormant — measuring and display continue, but nothing is switched over.

Switching over, log, reverting

Writing goes through the core's wp_set_option_autoload(), not through an UPDATE of our own: only that way are the right caches cleared afterwards, otherwise an external object cache would keep delivering the old state. On installations without this function, Kakapo sets “no” and clears alloptions, notoptions and the individual entry itself. Before writing, the row is checked afresh once more: does it still exist, is it still set to “loaded” at all, and how large is it at this moment — the log is meant to record what was really taken out of the loading process. If the database does not carry out the change, the message says so explicitly, and nothing was changed. The log keeps up to 200 entries with the old column value, size, time and user name. Reverting works individually or for all at once; what is written back is “loaded”, because WordPress's intermediate value “auto” cannot be restored through the core function — the original value stays visible in the log. If an option has disappeared entirely in the meantime, for instance because the plugin was uninstalled, Kakapo reports that and removes the pointless entry instead of claiming it was “reverted”.

Was this article helpful?