Persistent Object Caching

This post was contributed by Ryan Hellyer. He is from New Zealand, lives in Germany, and works as a full-time WordPress geek for Forsite Media in the Netherlands. He spends his time building WordPress plugins and getting up to mischief in his adopted home of Berlin.

I have an issue with WordPress caching plugins. It’s not that I don’t like using them, or that they’re junk (most are, but that’s a separate issue). No, the problem is that most people don’t have the foggiest idea how WordPress handles caching internally, and what causes their site to run faster.

Static page caching

Most caching plugins do what is called static page caching. They cache a complete page, including all of it’s HTML. This is terrific, as it means that WordPress doesn’t need to regenerate the page every time someone visits it, but it means that those pages will be out of date sometimes when content is updated. Anyone who has used these plugins can usually attest to cursing at their site due to to the cache not updating when required.

Object caching

For a very long time, WordPress has had a caching system baked into it. Most WordPress developers I’ve met have no idea this exists. Some have used transients, which are a part of the WordPress caching API, but in my experience, very few developers properly understand how they work.

By default, WordPress includes an internal caching system. If you use get_option( ‘something’ ); somewhere in your site, then run that same code later on in that page, WordPress will only need to load the data from the database once, as it caches it for use later on in the page load. It does this via the wp_cache_add(), wp_cache_set() and wp_cache_get() functions.

Transients behave in a similar way, but by default can store the data for use in subsequent page views by storing them in the database. Storing information in the database is resource intensive though, so transients must be used sparingly to avoid hammering the database too hard and actually causing the site to slow down rather than speed up.

What we need is the ability to store information in a persistent way (for use on more than the current page load), which can be written to and from extremely rapidly (unlike caching in the database).

Persistent object caching

Although the object caching system in WordPress was designed to only work on a single page load by default, the smart folks on the WordPress core team ensured that it was trivial to plug into this and provide a way to store data however you want and for as long as you want. Awesome!

A normal WordPress plugin cannot be used to provide persistent object caching in WordPress. You need to manually create a drop-in file called object-cache.php, which sits in the wp-content folder. Some of the larger (bloated?) plugins, will automatically generate this drop-in file in your wp-content folder.

Once installed, the object caching drop-in will cache anything utilizing the WordPress caching API. This includes transients, which will automatically stop using the default database layer and instead make use of whatever object caching back-end is available.

Some of the earlier implementations of object-cache.php files for WordPress simply stored the data in the database, or in flat static files. But there are a multitude of better backends/places to store small pieces of data like this, and there are many different object caching drop-ins available for WordPress to hook into these various systems.

In-memory data stores – ninja fast data storage

MySQL is fast, but nothing compares to just throwing some data into RAM for maximum performance. With this in mind, many people who are much smarter than I, have developed systems for allowing us to store random bits of data in the server’s RAM. The most popular of these is Memcached, but there are others including APC and Redis which are very popular. Since they store their data in RAM (when possible) and are designed to be fast rather than reliable, they are insanely fast at both data storage and retrieval.

With a database or flat file caching back-end, you can not refresh your cache rapidly, or store tiny bits of data. With an in-memory data store, those problems do not exist. For this reason, use of an in-memory data storage back-end can provide an enormous performance advantage to sites using them in conjunction with the WordPress object caching API.

To make use of one of these, simply ensure that Redis, Memcached or APC are installed on your server, then install one of their corresponding drop-in files (you have to get the correct one or all hell will break loose).

Memcached – https://wordpress.org/plugins/memcached/

Redis – https://wordpress.org/plugins/wp-redis/

APC – https://wordpress.org/plugins/apc/

Once you have an appropriate object caching drop-in installed, you should notice an immediate increase in performance. WordPress caches a lot of data internally and none of that will need to be queried on every page load.

It is entirely normal to see a stock WordPress installation go from 20+ MySQL queries per page down to 4 queries, as the object caching backend takes care of storing all of the data which does not change between page loads. The WordPress API always attempts to refresh the cache when required; there are some instances in which this does not work perfectly, but it is usually a flawless cache refreshing process.

Faster static page caching

There are ways to serve and refresh static page caching plugins via the WordPress object caching system too, including via the Batcache plugin, provided by the kind folks at Automattic. This is beyond the scope of this blog post, but it is worth investigating if you also require static page caching.

Conclusion

Caching within WordPress is complex. Object caching is a vital tool for your toolbox, as it can provide a huge performance improvement without requiring you to resort to full page caching.