{"id":113529,"date":"2024-06-18T16:14:21","date_gmt":"2024-06-18T16:14:21","guid":{"rendered":"https:\/\/make.wordpress.org\/core\/?p=113529"},"modified":"2024-10-01T16:14:31","modified_gmt":"2024-10-01T16:14:31","slug":"options-api-disabling-autoload-for-large-options","status":"publish","type":"post","link":"https:\/\/make.wordpress.org\/core\/2024\/06\/18\/options-api-disabling-autoload-for-large-options\/","title":{"rendered":"Options API: Disabling autoload for large options"},"content":{"rendered":"<p class=\"wp-block-paragraph\">WordPress automatically loads multiple options with a single query on each page request in order to be more efficient\u2014a technique called \u201cautoloading\u201d. Prior to <a href=\"https:\/\/core.trac.wordpress.org\/changeset\/57920\">[57920]<\/a>, developers could control whether their option should be autoloaded by passing either <code>\"yes\"<\/code>\/<code>true<\/code> or <code>\"no\"<\/code>\/<code>false<\/code> to the third parameter of <code>add_option()<\/code> or <code>update_option()<\/code>. However, the decision to make that parameter optional, with a default value of <code>\"yes\"<\/code> has led to many options being loaded on every page unnecessarily (see <a href=\"https:\/\/core.trac.wordpress.org\/ticket\/42441\">#42441<\/a>).\u00a0<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Autoloading a large amount of data that is not used negatively impacts website performance, particularly when an option containing a large amount of data is not used.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/core.trac.wordpress.org\/changeset\/57920\">[57920]<\/a> introduces several changes to the Options <span tabindex='0' class='glossary-item-container'>API<span class='glossary-item-hidden-content'><span class='glossary-item-header'>API<\/span> <span class='glossary-item-description'>An API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways.<\/span><\/span><\/span> to optimize autoloading behavior.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Changes to the options API<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To support this optimization for autoloading behavior, and to create a way to apply further optimizations going forward, the following changes to the Options API have been made.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">New default <code>$autoload<\/code> value<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The default value for the <code>$autoload<\/code> parameter of <code>add_option()<\/code> and <code>update_option()<\/code> is being changed from <code>\"yes\"<\/code> to\u00a0 <code>null<\/code>, to allow WordPress to differentiate between an option with an autoload value that is explicitly set, and one where it can dynamically determine whether an option should be autoloaded. As a result, there are now three recommended values for the autoload parameter:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>true<\/strong>: always autoload; Use this when an option should load on every page to avoid an additional DB query.<\/li>\n\n\n\n<li><strong>false<\/strong>:\u00a0 never autoload; Use this when an option is rarely used to avoid wasted data being loaded on every page.<\/li>\n\n\n\n<li><strong>null<\/strong>: maybe autoload; Allow the autoload value to be dynamically determined. By default, WordPress will still autoload options using the default value unless they contain large values (described below).<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">For backwards compatibility, the previous values of <code>\"yes\"<\/code> and <code>\"no\"<\/code> are still supported and mapped to <code>true<\/code> and <code>false<\/code>, respectively.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Updated database autoload values<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Previously, all options were stored in the database with an autoload value of either <code>\u201cyes\u201d<\/code> or <code>\u201cno\u201d<\/code>. Starting with this change, the autoload value for newly updated options will now be one of the following values:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u2018<strong>on\u2019:<\/strong> Added with an explicit <code>true<\/code> value and MUST be autoloaded (needed on EVERY page).<\/li>\n\n\n\n<li>\u2018<strong>off<\/strong>\u2018<strong>:<\/strong>\u2018 Added with an explicit <code>false<\/code> value and MUST not be autoloaded (e.g. only used on a single <span tabindex='0' class='glossary-item-container'>admin<span class='glossary-item-hidden-content'><span class='glossary-item-header'>admin<\/span> <span class='glossary-item-description'>(and super admin)<\/span><\/span><\/span> page) .<\/li>\n\n\n\n<li>\u2018<strong>auto\u2019:<\/strong> Added without an explicit value and will rely on WP default autoloading behavior. In WordPress 6.6 these SHOULD autoload, but the default may change in the future.<\/li>\n\n\n\n<li>\u2018<strong>auto-on\u2019:<\/strong> Added with a dynamically set to <code>true<\/code> value and SHOULD be autoloaded.<\/li>\n\n\n\n<li>\u2018<strong>auto-off\u2019:<\/strong> Added with a dynamically set to <code>false<\/code> value and SHOULD NOT be autoloaded.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">No upgrade routine is planned for this change, so previously added options will still be stored with <code>\u201cyes\u201d<\/code> or <code>\u201cno\u201d<\/code> values, which will be treated like <code>\u201con\u201d<\/code> and <code>\u201coff\u201d<\/code>, respectively. If you have implemented any custom SQL to read or write autoload values, you should update them to use the new values.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Newly introduced public functions and filters<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Several new functions and filters are available to make working with the new autoload values easier.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">New Function<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><code>wp_autoload_values_to_autoload()<\/code><\/strong> \u2013 Returns all database values that should be autoloaded. Defaults to an array containing <code>'yes'<\/code>, <code>'on'<\/code>, <code>'auto-on'<\/code>, and <code>'auto'<\/code>.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">New Filters<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><code>wp_autoload_values_to_autoload<\/code><\/strong> \u2013 Edit the list of autoload values stored in the database values that should be autoloaded. At this time, the <span tabindex='0' class='glossary-item-container'>filter<span class='glossary-item-hidden-content'><span class='glossary-item-header'>Filter<\/span> <span class='glossary-item-description'>Filters are one of the two types of Hooks <a href=\"https:\/\/codex.wordpress.org\/Plugin_API\/Hooks\">https:\/\/codex.wordpress.org\/Plugin_API\/Hooks<\/a>. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output.<\/span><\/span><\/span> only allows values to be removed.<\/li>\n\n\n\n<li><strong><code>wp_default_autoload_value<\/code><\/strong> \u2013 Determine the default autoload value for an option where no explicit value is passed. Return a boolean <code>false<\/code> value to disable autoloading.<\/li>\n\n\n\n<li><strong><code>wp_max_autoloaded_option_size<\/code> \u2013 <\/strong>Modify the size threshold above which options will not be autoloaded by default. Defaults to <code>150000<\/code>, i.e., 150k bytes.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Disabling autoload for large options<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To address the issue of autoloading excessively large options, when an option is added via <code>add_option()<\/code> or an option\u2019s value is changed via <code>update_option()<\/code>, WordPress will now dynamically disable the autoload behavior by checking the size of the value before updating the database. For any options that do not explicitly pass <code>true<\/code> to the <code>$autoload<\/code> parameter, a value that is greater than 150k bytes will no longer be set to autoload.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Preparing for this update<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To prepare for this update, developers should update calls to <code>add_option()<\/code> and <code>update_option()<\/code> in their code to explicitly set an autoload value using the new preferred <code>true<\/code> or <code>false<\/code> values in order to control the autoload behavior for your options. Otherwise, continue using the default value to allow for autoload optimizations to be dynamically applied.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Ensuring a large option is still autoloaded<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">If you need to ensure a specific large option is autoloaded after this change and cannot directly change the code where that option is saved, you can make use of the new <code>wp_default_autoload_value<\/code> filter.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Note: Do this with care, and only for options that are needed on every page.<\/em><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\nadd_filter( 'wp_default_autoload_value', 'my_large_value_autoload', 10, 2 );\n\nfunction my_large_value_autoload( $autoload, $option ) {\n    if ( 'my-large-option' === $option ) {\n        return true;\n    }\n    \n    return $autoload;\n}\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\">Adjusting the threshold for large options<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">If you want to change the size threshold for when options should no longer be autoloaded, you can use the new <code>wp_max_autoloaded_option_size<\/code> filter. Increasing this value is not recommended, as it could lead to slower performance.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\nadd_filter( 'wp_max_autoloaded_option_size', 'my_max_autoload_option_size' );\n\nfunction my_max_autoload_option_size( $size ) {\n    \/\/ Reduce the threshold for large sizes to 100K (Default is 150K).\n    return 100000;\n}\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\" id=\"auditing-your-site-for-large-options\">Auditing your site for large options<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/core.trac.wordpress.org\/ticket\/61276\">WordPress 6.6 will include a new Site Health check<\/a>, which will display a critical issue that says \u201cAutoloaded options could affect performance\u201d if the total size of your autoloaded options exceeds 800 KB.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To audit your site for large options that are currently being autoloaded, you can run an enhanced version of this same Site Health check by installing the <a href=\"https:\/\/wordpress.org\/plugins\/performance-lab\/\">Performance Lab plugin<\/a> from the WordPress Performance Team. Once activated, the <span tabindex='0' class='glossary-item-container'>plugin<span class='glossary-item-hidden-content'><span class='glossary-item-header'>Plugin<\/span> <span class='glossary-item-description'>A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory <a href=\"https:\/\/wordpress.org\/plugins\/\">https:\/\/wordpress.org\/plugins\/<\/a> or can be cost-based plugin from a third-party.<\/span><\/span><\/span> will add additional information to the Site Health check so you can review and disable any options that do not need to be autoloaded in the Site Health check.<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1600\" height=\"1077\" data-attachment-id=\"113668\" data-permalink=\"https:\/\/make.wordpress.org\/core\/2024\/06\/18\/options-api-disabling-autoload-for-large-options\/image-2-15\/#main\" data-orig-file=\"https:\/\/make.wordpress.org\/core\/files\/2024\/06\/image-2.png\" data-orig-size=\"1600,1077\" data-comments-opened=\"1\" data-image-meta='{\"aperture\":\"0\",\"credit\":\"\",\"camera\":\"\",\"caption\":\"\",\"created_timestamp\":\"0\",\"copyright\":\"\",\"focal_length\":\"0\",\"iso\":\"0\",\"shutter_speed\":\"0\",\"title\":\"\",\"orientation\":\"0\"}' data-image-title=\"image-2\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/make.wordpress.org\/core\/files\/2024\/06\/image-2-1024x689.png\" src=\"https:\/\/make.wordpress.org\/core\/files\/2024\/06\/image-2.png\" alt=\"\" class=\"wp-image-113668\" style=\"width:840px;height:auto\" srcset=\"https:\/\/make.wordpress.org\/core\/files\/2024\/06\/image-2.png 1600w, https:\/\/make.wordpress.org\/core\/files\/2024\/06\/image-2-300x202.png 300w, https:\/\/make.wordpress.org\/core\/files\/2024\/06\/image-2-1024x689.png 1024w, https:\/\/make.wordpress.org\/core\/files\/2024\/06\/image-2-768x517.png 768w, https:\/\/make.wordpress.org\/core\/files\/2024\/06\/image-2-1536x1034.png 1536w\" sizes=\"auto, (max-width: 1600px) 100vw, 1600px\"><figcaption class=\"wp-element-caption\">Screenshot of the advanced table shown by the Performance Lab plugin<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Other changes to the Options API in WordPress 6.6<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Introduce <code>wp_prime_network_option_caches()<\/code> to load multiple <span tabindex='0' class='glossary-item-container'>network<span class='glossary-item-hidden-content'><span class='glossary-item-header'>network<\/span> <span class='glossary-item-description'>(versus site, blog)<\/span><\/span><\/span> options with a single database request (<a href=\"https:\/\/core.trac.wordpress.org\/ticket\/61053\">#61053<\/a>)<\/li>\n\n\n\n<li>Prime transient and transient timeout options in the transient and site transient APIs (<a href=\"https:\/\/core.trac.wordpress.org\/ticket\/61193\">#61193<\/a>, <a href=\"https:\/\/core.trac.wordpress.org\/ticket\/61053\">#61053<\/a>)<\/li>\n\n\n\n<li>Update default autoload values used in <span tabindex='0' class='glossary-item-container'>core<span class='glossary-item-hidden-content'><span class='glossary-item-header'>Core<\/span> <span class='glossary-item-description'>Core is the set of software required to run WordPress. The Core Development Team builds WordPress.<\/span><\/span><\/span> (<a href=\"https:\/\/core.trac.wordpress.org\/ticket\/61045\">#61045<\/a>)<\/li>\n\n\n\n<li>Add <code>'label'<\/code> argument to <code>register_setting()<\/code> (<a href=\"https:\/\/core.trac.wordpress.org\/ticket\/61023\">#61023<\/a>)<\/li>\n<\/ul>\n\n\n\n<p class=\"has-text-align-right wp-block-paragraph\"><em>This post has been co-authored by <a href=\"https:\/\/profiles.wordpress.org\/pbearne\/\" class=\"mention\"><span class=\"mentions-prefix\">@<\/span>pbearne<\/a> and <a href=\"https:\/\/profiles.wordpress.org\/joemcgill\/\" class=\"mention\"><span class=\"mentions-prefix\">@<\/span>joemcgill<\/a><\/em><\/p>\n\n\n\n<p class=\"has-text-align-right wp-block-paragraph\"><em>Props to <a href=\"https:\/\/profiles.wordpress.org\/flixos90\/\" class=\"mention\"><span class=\"mentions-prefix\">@<\/span>flixos90<\/a>, <a href=\"https:\/\/profiles.wordpress.org\/peterwilsoncc\/\" class=\"mention\"><span class=\"mentions-prefix\">@<\/span>peterwilsoncc<\/a>,<a href=\"https:\/\/profiles.wordpress.org\/adamsilverstein\/\" class=\"mention\"><span class=\"mentions-prefix\">@<\/span>adamsilverstein<\/a>, <a href=\"https:\/\/profiles.wordpress.org\/mukesh27\/\" class=\"mention\"><span class=\"mentions-prefix\">@<\/span>mukesh27<\/a> and <a href=\"https:\/\/profiles.wordpress.org\/desrosj\/\" class=\"mention\"><span class=\"mentions-prefix\">@<\/span>desrosj<\/a> <\/em><br><em>for contributing to and reviewing this post.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n<p><a href=\"https:\/\/make.wordpress.org\/core\/tag\/6-6\/\" class=\"tag\"><span class=\"tag-prefix\">#<\/span>6-6<\/a>, #dev-note, <a href=\"https:\/\/make.wordpress.org\/core\/tag\/dev-notes\/\" class=\"tag\"><span class=\"tag-prefix\">#<\/span>dev-notes<\/a>, <a href=\"https:\/\/make.wordpress.org\/core\/tag\/dev-notes-6-6\/\" class=\"tag\"><span class=\"tag-prefix\">#<\/span>dev-notes-6-6<\/a><\/p><nav class='o2-post-footer-actions'><ul class='o2-post-footer-action-row'><\/ul><div class='o2-post-footer-action-likes'><\/div><ul class='o2-post-footer-action-row'><\/ul><\/nav>","protected":false},"excerpt":{"rendered":"<p>WordPress automatically loads multiple options with a single query on each page request in order to be more efficient\u2014a technique called &#8220;autoloading&#8221;. This feature can impact performance so WordPress 6.6 introduces several changes to the Options API to optimize autoloading behavior.<\/p>\n","protected":false},"author":125013,"featured_media":0,"comment_status":"open","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"_crdt_document":"","advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[1175],"tags":[5400,1443,5598],"class_list":["post-113529","post","type-post","status-publish","format-standard","hentry","category-general","tag-6-6","tag-dev-notes","tag-dev-notes-6-6","mentions-adamsilverstein","mentions-desrosj","mentions-flixos90","mentions-joemcgill","mentions-mukesh27","mentions-pbearne","mentions-peterwilsoncc","author-pbearne"],"revision_note":"","jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p2AvED-tx7","_links":{"self":[{"href":"https:\/\/make.wordpress.org\/core\/wp-json\/wp\/v2\/posts\/113529","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/make.wordpress.org\/core\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/make.wordpress.org\/core\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/make.wordpress.org\/core\/wp-json\/wp\/v2\/users\/125013"}],"replies":[{"embeddable":true,"href":"https:\/\/make.wordpress.org\/core\/wp-json\/wp\/v2\/comments?post=113529"}],"version-history":[{"count":19,"href":"https:\/\/make.wordpress.org\/core\/wp-json\/wp\/v2\/posts\/113529\/revisions"}],"predecessor-version":[{"id":115630,"href":"https:\/\/make.wordpress.org\/core\/wp-json\/wp\/v2\/posts\/113529\/revisions\/115630"}],"wp:attachment":[{"href":"https:\/\/make.wordpress.org\/core\/wp-json\/wp\/v2\/media?parent=113529"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/make.wordpress.org\/core\/wp-json\/wp\/v2\/categories?post=113529"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/make.wordpress.org\/core\/wp-json\/wp\/v2\/tags?post=113529"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}