Autoloaded options
The Options API is a built-in WordPress method for storing simple key-value data related to theme settings, widget settings, plugin settings, global site settings, and more. Data that is stored using the Options API can be found in the wp_options
database table.
Consider the size of an option’s content—and whether it should autoload or not—when using the Options API to add an option to an application.
- All of a site’s current options can be viewed within the WordPress Admin dashboard for logged-in users with the
manage_options
capability at the path/wp-admin/options.php
. - Options can be managed with the WP-CLI command
wp option
.
Caution
The Options API functions add_option()
and update_option()
accept a parameter $autoload
which defaults to yes
, which may not be desirable for every option introduced into a WordPress application.
When a WordPress site receives a request, all of the options marked as autoload = yes
are fetched and stored in memory for the application code to reference. This process is optimized by loading the collection of options into a Memcached key named alloptions
, which improves the speed at which the application loads and uses these option values.
Though the default for the autoload
parameter is yes
, it is very important to be selective about which options are autoloaded. Options necessary for most of the requests to a WordPress site are appropriate to autoload. If an option is large in size, used less frequently, or changes with a high frequency, it should be set as autoload = no
.
On VIP, all Memcached objects have a limit of 1 MB per object (compressed). This limit applies to the content of the alloptions
cache, and is specifically enforced for the alloptions
cache key. This limit is in place to protect sites from the negative performance impacts of loading too much data in alloptions
.
Identifying and resolving issues
Issues related to alloptions
most commonly occur when its size grows close to the 1 MB limit. As the size of a site’s alloptions
gets closer to 1 MB, the site will experience negative performance implications and possibly become unavailable until the root cause of the issue is fixed. Sites that become unavailable for this reason will return an HTTP status code 503
, with a display error Error 1024 (alloptions)
.
If a site is experiencing issues related to the size of alloptions
:
- Identify which options are the biggest.
- Backup and audit the problematic options.
- If possible, delete the problematic option(s) or set it to
autoload = no
. - Determine the root cause for why the option increased to its problematic size.
- Resolve the root cause to prevent the site’s performance from being further impacted.
Identify big options with Query Monitor
The Autoloaded Options panel in Query Monitor displays the options of a site that are autoloaded, their size, and additional information that can be helpful for debugging.
Identify big options with VIP-CLI
Identify the largest options that are stored in alloptions
and their size with the custom VIP WP-CLI command: wp vip alloptions find --big
An example of this command and its possible output:
$ vip @example-app.develop -- wp vip alloptions find --big Success: Big options for https://example.com - Blog ID 1: +---------------------------------+--------+ | name | size | +---------------------------------+--------+ | large | 512000 | | rewrite_rules | 22387 | | wp_user_roles | 7967 | | jetpack_available_modules | 1211 | | jetpack_constants_sync_checksum | 1183 | | subscription_options | 529 | +---------------------------------+--------+ Total size of all option values for this blog: 541 KB Size of serialized alloptions for this blog: 555 KB use `wp option get <option_name>` to view a big option use `wp option delete <option_name>` to delete a big option use `wp option autoload set <option_name> no` to disable autoload for option
For multisites, target a specific network with the --url
parameter. For example:
vip @example-app.develop -- wp vip alloptions find --big --url=example.com
Save a backup of a site’s options
Retrieve the value of a specific option with the WP-CLI command wp option get
. Save the output to a file on a user’s local machine. In this command example, the value of the rewrite_rules
option is retrieved and saved to a file in json
format:
vip @example-app.develop -- wp option get rewrite_rules --format=json 2>&1 | tee rewrite_rules.json
A prompt for confirmation will appear in the terminal for CLI commands that are run against a production environment. The output of this prompt will be saved to the output file. If necessary, it is possible to skip the confirmation by including --yes
in the command.
For multisites, target a specific network with the --url
parameter. For example:
vip @example-app.develop -- wp option get rewrite_rules --url=example.com --format=json 2>&1 | tee rewrite_rules.json
Disable autoload for an option
When disabling autoload for an option with the WP-CLI method, it is important to investigate if the option was originally added or updated in the application code. The code will likely need to be modified to prevent the option from reverting to autoloading.
Disabling autoload for an option will not delete or remove the option. After an option is removed from alloptions
, any code that references that option will initially need to fetch the value of that option from the database. The fetched value will then be cached separately and available for future requests.
To stop an option from autoloading and being added to alloptions
, update its record in the database with the WP-CLI command: wp option autoload set <option_name> no
For example:
vip @example-app.develop -- wp option autoload set <option_name> no
For multisites, target a specific network with the --url
parameter. For example:
vip @example-app.develop -- wp option autoload set <option_name> no --url=example.com
Disable autoload for redirect options in Yoast SEO Premium
Since v17.7 of the Yoast SEO Premium plugin, 2 options used to calculate redirect destinations are autoloaded to save 2 queries. As the number of redirect destinations increases for a site using object caching, it becomes more likely that alloptions
will exceed the 1 MB maximum object size limit.
Yoast SEO Premium v20.13 has introduced a method for disabling the autoloading of the redirect options.
Clear the alloptions
cache
If an option in alloptions
is modified directly in the database—or if an option’s updated value does not appear to be loading as expected—the object cache should be cleared to ensure that the most accurate data is being stored in the cache. Clear the object cache with the wp cache delete
WP-CLI command, including alloptions
as the cache key and options
as the cache group.
An example of this command and its output when the command is successful:
$ vip @example-app.develop -- wp cache delete alloptions options =================================== + command: wp cache delete alloptions options =================================== ✔ Are you sure you want to run this command on PRODUCTION for site wpvip.com? (y/N) · true Success: Object deleted.
For multisites, target a specific network with the --url
parameter. For example:
vip @example-app.develop -- wp cache delete alloptions options --url=example.com
Custom alerting for ALLOPTIONS
Use the vip_alloptions_safeguard_notify
action to trigger custom alerting when ALLOPTIONS
has grown to a size that can lead to degraded application performance. For example, custom alerting can notify a chat application or escalation monitoring system.
In this code example, the vip_alloptions_safeguard_notify
hook is configured to trigger an email alert if the size of ALLOPTIONS
has grown too large. Code similar to this example can be added to a theme’s functions.php
, or added as part of a custom plugin or MU plugin.
<?php
add_action( 'vip_alloptions_safeguard_notify', 'vip_email_alloptions_size', 10, 1 );
/**
* Sends detailed email when ALLOPTIONS is past a VIP defined concerning threshold.
*
* @param bool $really_blocked False if alloptions size is large. True if site loading is being blocked.
*/
function vip_email_alloptions_size( bool $really_blocked ) {
// Example uses the site's administrator email from Settings > General > Administration Email Address.
$email_recipient = get_bloginfo( 'admin_email' );
$environment = ( ( defined( 'VIP_GO_APP_ENVIRONMENT' ) && VIP_GO_APP_ENVIRONMENT ) ? VIP_GO_APP_ENVIRONMENT : 'unknown' );
// The code that activates the `vip_alloptions_safeguard_notify` hook stores these values in the cache for easy retrieval.
$alloptions_size = wp_cache_get( 'alloptions_size' );
// Customize email subject based on level of urgency.
if ( $really_blocked ) {
$subject = sprintf(
'Urgent - ALLOPTIONS blocking site %s (%s)',
esc_url( home_url() ),
esc_html( $environment )
);
$blocked_status = 'This site is currently BLOCKED from loading and will be until option sizes are reduced.';
} else {
$subject = sprintf(
'Caution - ALLOPTIONS is up to %s on %s (%s)',
esc_html( size_format( $alloptions_size ) ),
esc_url( home_url() ),
esc_html( $environment )
);
$blocked_status = 'Site will be blocked from loading if option sizes get too much bigger.';
}
$size = '';
$message = sprintf(
"Alloptions size when serialized: %s (%s)\n\n",
esc_html( size_format( $alloptions_size ) ),
esc_html( $alloptions_size )
);
$message .= $blocked_status . "\n\n";
$message .= 'Additional information: https://docs.wpvip.com/code-quality/working-with-wp_options/';
wp_mail( $email_recipient, $subject, $message );
}
Considerations
- Be careful how data in
alloptions
is modified. Becausealloptions
is stored in Memcached, WordPress must rebuild the cache for a key when its data changes. This can hurt a site’s performance. If data needs to be stored for quick retrieval by a site, store it in the object cache without usingalloptions
. - Only store the minimum data necessary in
wp_options
. Instead of storing the whole HTML fragment, consider storing a set of post ids or configuration settings and having the application code build the HTML from that information. - Widgets are stored in
wp_options
. Avoid storing large amounts of content in free text widgets, like the HTML or text widgets. Consider using a custom post type to store and retrieve that data instead.
Last updated: March 12, 2024