When working on a site, blog, or project on WordPress, it’s not at all uncommon to hear users (developers, designers, bloggers, and so on) talk about caching.

Caching can be a tricky subject to tackle, though. I think that most people have an understanding that caching, in general, can be used to speed up a site. But regarding what it does, how it works, and any other details beyond that are hit-or-miss, pun intended, depending on your level of experience.

And one area in which I see – and have personally experienced – is the understanding of the WordPress Object Cache. Feel free to click the link, though it’s far more advanced than what I plan to cover in this article.

That is, WordPress provides some basic functionality for loading the options in the wp_options database table, but how WordPress caches data, how WordPress retrieves non-cached data, and how it works is often glossed over or assumed to be a sort of magic.

The Magic of WordPress

How it feels to work with the magic of WordPress (and not understanding what’s happening).

So I thought it might be worth sharing a few notes about the WordPress Object Cache and how it works with objects if for no other reason that to provide a quick reference for what it is, how it works, and how we, as developers, can leverage it to our advantage.

The WordPress Object Cache

Simply defined:

The WordPress object cache is a way that we can store information in memory for a given page.

In other words, if we write something in the object cache and then navigate to another page, the value will not be available in the cache.

The idea behind the object cache is to take information that might require a complex query and store the results in memory so that you can use that information throughout the rest of the page without having to execute the query multiple times. It can also be used to more quickly retrieve other types of data that you may frequently use throughout a page, as well.

Regardless of how you look at it, the results are retrieved once and are then available in as many places as you need them.

That said, if you’re looking to have the information available on multiple pages as you navigate throughout the site, then you’ll need to leverage persistent caching. This is software that will take the information that’s stored in memory for the given page load and make it accessible across various pages.

That type of software or plugins is beyond the scope of this post (though if you’re familiar with something like the Memcached Object Cache or Redis, then you’re familiar with such software).

How Does This Relate To Options?

If you’ve done any theme or plugin development that saves and retrieves options from the database, then you’ve likely worked with at least one or two of the following API functions:

The first two will write information to the database while the third will retrieve the information from the database. But let’s say, using a bit of a contrived-and-vague-example, that you’re serializing a semi-complex data structure, and you don’t want to have to hit the database every single time you want to retrieve the result.

In this case, you can add this to option to the database and pass true as your fourth argument (the third will need to be specified with an empty string as it’s deprecated) in the add_option call. This will instruct WordPress to, when it loads the options, which it should load the value of this option into its object cache when a page loads.

And, as of WordPress 4.2, you can also pass true to update_option if you want to autoload the values that way, too (that is, if you’re one of those like some of us who just use update_option regardless :).

When you request the value of the option, it will first check the object cache. If it’s available in memory, it will grab it from there (and it will happen quickly). If on the other hand, it’s not found in the cache, it will then attempt to read it from the database.

How Does This Work?

This is where it gets a little more technical (not to be confused with “boring” so keep reading!).

Whenever you make a call to get_option, WordPress core will make a call to a function called wp_load_alloptions . Earlier, I mentioned that WordPress would look for an option’s value in memory before hitting the database.

That’s true, to an extent, and this is where all of that occurs.

WordPress Object Cache: How It Works

Once  wp_load_alloptions , it will grab all of the autoloaded options from the cache (or it will populate the cache with those options). These options will be stored in an array that’s written to memory.

So when I was talking about passing true to add_option in the section above, this is where it comes back into play. When you do this, you’re telling WordPress you want the option to load when wp_load_alloptions is invoked.

In short, wp_load_alloptions will return an array of all of the autoloaded options. Here’s the nice thing about the function, though: If your option isn’t marked to autoload, then WordPress will first check the cache, and then will grab the value from the database and then store it into the cache.

What About Getting Options?

More often than not, you’re going to be making multiple calls to get_option especially if you’re working with a more advanced plugin. The question naturally arises:

Should I be concerned with making multiple calls to this function throughout my plugin, my template, or my project on a given page load?

Since, as mentioned above, WordPress will ultimately retrieve the data from the database if it finds it nowhere else, then that information will be accessible via the cache in subsequent calls.

There’s Always More

Everything about the WordPress object cache that I’ve provided above should be enough to give you a basic understanding of how it works and its benefits. It may also explain why there are times where it’s better to use add_option rather than blindly using update_option (something I’m guilty of doing in previous projects).

But I also know that the details behind this can get much more technical. So if there’s something I’ve left out that you think should be added, if there’s something worth correcting, or if there are other questions, please leave them in the comments.


And thanks: I also want to give a shout out to Carl Alexander for proofing this particular article to make sure it struck a balance between a simple primer and between nailing technical details at a level that wouldn’t make other people’s eyes gloss over.

Category:
Articles
Tags:

Join the conversation! 11 Comments

  1. Thanks for the article. I’ve struggled with retrieving correct values from the options table when various forms of caching are enabled.

    This is the part that doesn’t make sense to me:

    “Here’s the nice thing about the function, though: If your option isn’t marked to autoload, then WordPress will first check the cache, and then will grab the value from the database and then store it into the cache.”

    If we say $autoload = ‘no’, then why would WordPress ever store it in the cache?

    Or did I understand that incorrectly?

    Thanks

    Eric

    • If we say $autoload = ‘no’, then why would WordPress ever store it in the cache?

      This is an easy point of confusion, so don’t even sweat it! 

      autoload refers to the idea of placing options into memory as soon as the page loads.

      If autoload is set to false then that won’t happen on page load.

      But let’s say you request the value when the page is loading. Then, it will grab it from the database and then place it into the cache so any subsequent loads on that page will come from the cache, not the database.

      Make sense?

  2. Quick correction, autoload is the 4th argument to add_option(), not 3rd. Thanks for the article.

    • Thanks! The third argument of add_option is deprecated so autoload can be used as the third. You can see this in the source code, too.

      • Really? What line(s)? I looked at the source code via codex since I’m on a tablet. I don’t see it. Thanks!

          • Hey Tom,

            The function _deprecated_argument() sets up a hook and then logs the use of a deprecated argument if WP_DEBUG == true. I just created a simple plugin with this one line:

            add_option(‘Test Option’, ‘Test Value’, true);

            Ran it, then queried the DB.

            mysql> select * from wp_options where option_name = ‘Test Option’\G

            *************************** 1. row ***************************

            option_id: 990

            option_name: Test Option

            option_value: Test Value

            autoload: no

            1 row in set (0.00 sec)

            So, unless I missed something which is very possible, autoload needs to be the 4th parameter.

            • What version of WordPress are you using? I just did this in a default installation of WordPress 4.6:

              `

              add_action( ‘init’, ‘tom_options_test’ );

              function tom_options_test() {

              add_option( ‘this-is-a-test’, ‘tom’, true );

              update_option( ‘this-is-a-test-as-well’, ‘tom’, true );

              update_option( ‘this-is-a-test-as-well-2’, ‘tom’, false );

              }
              `

              And the corresponding database columns look like this: http://d.pr/i/12URB

              Curious to know as there’s obviously confusion around this and I want to make sure the article is as clear as possible :).

  3. I think I’ve got it figured out. First off, my apologies on my previous post, I must have copied and pasted the wrong data because I couldn’t reproduce my own results. Serves me right for trying to be productive at 2:45 am.

    Now that I have some coffee in me, I think I confirmed ‘autoload’ needs to be the 4th argument to add_option(). The reason your code was producing results of autoload == ‘yes’ is because ‘true’ is the default value when no argument is supplied. So regardless of what you use as the third argument, autoload will always be true. The line of code that will tell you if the third parameter can or can’t be used for autoload is this:

    add_option(‘Test Option’, ‘Test Value’, false);

    You’ll see that autoload will still be set to ‘yes’ in the DB even though the third argument is false.

    The signature of update_option() is different so I’m leaving that out. Let me know if I screwed up again, still very possible. ;)

    • You’re correct (and sorry it took so long to get back to this particular comment). Tested this in a few different ways and everything you’ve mentioned is right on.

      I’ve updated the post accordingly, too. Thanks for the clarification on this :).

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.