WordPress Caching: The Six Different Things People May Mean

“Caching” is, generally, the solution you hear offered for most performance problems a WordPress site has. For things other than WordPress sites, too, caching is one of the easiest and most effective ways to increase performance of software without investing in new hardware. (Using the exact same software on hardware that is significantly faster is easier, but probably not cheaper…)

But like so many things that experts talk about casually, I think the aspiring WordPress developer is likely to be at least a little confused by the various things that fall under the banner of “caching” in a WordPress site. Our goal here, then, is not to teach you how to use caching to make your WordPress site three times faster, but to help you understand the various meanings of “caching” and how each may, or may not, be the ideal way for you to speed up your WordPress site.

Broadly there are three kinds of caching that make your WordPress site faster:

  • Static asset caching — keeping your images, stylesheets, and scripts more available
  • Whole page caching — keeping “rendered” WordPress pages and serving those rather than having WordPress remake them
  • Partial caching — where intermediate results are kept closer at hand for later use

The article’s title mentions six ways “caching” is done, but that list only has three members. What gives?

This list is the five-thousand foot view, but there are nuances that the above list necessarily glosses over. In fact, I said six caching layers because each of the above types of caching can be done in two different ways on most WordPress sites. And understanding how that’s possible, or why it happens, is why you should read on.

Asset Caching: The Easy Help for Your Server

Your browser may easily make dozens if not hundreds of requests to show you a specific page.

So, you probably know this, but an individual page visited by someone on your WordPress site is not responded to with one single glob of stuff sufficient to render what their browser shows. WordPress doesn’t say “Here’s WPShout’s whole index page.” Instead, it tells the browser, “Here’s the map of WPShout’s index, and it shows you all the other resources you’ll need.” Those other resources are images that the HTML references, the stylesheets that affect it, and the JavaScript files that may further alter its behavior.

Your browser may easily make dozens if not hundreds of requests to show you a specific page. For our index page, as I wrote this piece, Firefox reported over 10SixHardDriveFormFactors0 requests on the page. About 36 were made by our source itself, the rest were made by things like our Facebook and Twitter widgets. The images, our stylesheets, and JavaScript files were only a few dozen, but even those can be served at varying speeds.

One possibility, and what we’d call the “cache-less” one, is that each of those is static assets a file sitting on our servers storage drive (be that a spinning disk or flash storage). In that case, as the browser requested each Apache would then seek, find, and send down the the visitor each one as the requests comes in. Especially with a spinning hard disk, all this need to seek and find in the storage of the server could be slow.

So the first kind of caching you can have is that those files are kept in your server’s temporary memory (RAM), rather than needing to be read from storage. I’m no expert, but I think that both Apache and Nginx are likely to do a good deal of this for you by default, though I do know that our friends at SiteGround include this on their list of caching features, so perhaps special system administration is required for it. In any case, this is our caching meaning #1.

Caching meaning #2 is related, and one of the more complicated types of caching you’ll hear people talk about. #2 is a content delivery network, or CDN. We won’t go into exhaustive details — this article is long enough and I’m no expert on the topic — but CDNs are a way that static assets are cached closer to the person and internet connection currently viewing a page. If my server is in Dallas and someone if browsing my site from Kolkata, every asset I link requires a half-the-world trip. Even at the speed of light (the theoretical limit for how fast a network can be) that’s not instantaneous. But if I have a CDN in Bangalore, I can deliver my images and stylesheets far faster to my Indian visitors. Effectively, a CDN is just a bunch of servers that only hold certain of your files and give your visitors those files from the closest one.

Whole Page Caching: Leave WordPress Out of It

The creation of the HTML that your browser first gets from the server is another place that you can add speed to a site with caching.

We mentioned in the last section that when you visit the WPShout index, you’re not getting a complete browser-viewable dataset, but a map to it. The last section is about filling out the map-directed dataset, this section is about the map. Said differently: the creation of the HTML that your browser first gets from the server is another place that you can add speed to a site with caching.

The idea here is that WordPress does a number of things to put together its final HTML for the browser: it processes a URL, it makes a database query or a dozen to get the data for the page matched to the URL, it then processes your theme files to put that database data into your templates, and finally it sends it all to the server which then sends it down to the user. This can frequently all be done in a matter of millisecond, but when you want to stay up when your Super Bowl ad airs, those milliseconds matter a lot.

So what you can do is cache that final HTML set that matches a given URL and then serve that for a period of time, rather than making WordPress regenerate it. Sure, it may mean that a new comment or slightly changed sidebar widget isn’t as fresh for the hour-or-so you serve the cached HTML, but it also means you server won’t fall over.

varnishcache_rgb-gimp2-alphaThis can be done two ways: via a separate process, or via a WordPress plugin. Let tackle the separate process as our #3 meaning of caching, a reverse proxy like Varnish. Nginx — which you may know as a alternative web server to Apache — is also frequently used in this capacity. Basically, in these cases the reverse proxy (Varnish) catches your WordPress-rendered HTML before it’s sent down to your visitor. The next time a visitor asks for the same page, Varnish serves up its “caught” version and WordPress doesn’t even need to be bothered with that request. Because Varnish (or Nginx, properly configured) is purpose-built for this use, its super fast. In WordPress hosting, you’ll need to go to a WordPress specific host to get this kind of caching though, and its generally not something you can configure in your WordPress admin. (Our partner, SiteGround, has a plugin that cooperates with their reverse proxy cache; I’m guessing some other hosts offer a similar feature, but I have to admit ignorance of specifics.)

If your host doesn’t offer you a whole-page caching layer with a separate process on its server, your next best stop to get this sort of functionality is a WordPress plugin like WP Super Cache. You may have guessed, but this generally isn’t quite as performant, because you’re relying on PHP (rather than a faster language like C, which Varnish and Nginx use) and because you’re doing this all in the same process as the WordPress itself. You can still realize substantial performance wins from a WordPress plugin doing full-page caching (our #4 caching meaning), but you may sometimes see memory issues with sort of solution. (Basically, you use more memory than you will without this solution because PHP is both catching its output and doing all the normal stuff. It’s not insurmountable, but you may need to go tweak a php.ini value or two…)

Partial Caching: Of Transients and More…

The final class of “caching” layers are when you store intermediate data rather than relying on refetching or rebuilding it every time.

The final class of “caching” layers are when you store intermediate data rather than relying on refetching or rebuilding it every time. We’ve covered the idea of WordPress Transients API before, but basically that’s where this is.

Transients are most often prescribed when you’re making HTTP API requests — say to Github, or Facebook, etc. If you were trying to get data about a Github repository for a sidebar widget, no caching has a lot of steps. Once the visitor asks for your site, then you ask Github’s endpoint for the data, it processes your request, sends its response back to you, you process it, then you can respond to your visitor — it’s really slow. So you cache what you got back from Github, and then only do all those Github steps once every few hours. This way only one, rather than every, page load has to wait for the process.

How are there two versions here, when we just talked about the “Transients API” as a single thing? Well, a lesser-understood thing about the caching and performance benefits of transients is that they work two different ways, depending on how your WordPress site is configured.memcached-wordpress-api-caching

If your host offers a “dynamic cache” — most WordPress specific hosting plans, and (again) our partners at SiteGround do — transients are stored in an in-memory store, usually Memcached. So #5 is “partial”, “fragment”, or “dynamic” caching in a memory store like Memcached or Redis. If this is enabled, WordPress will store all transients explicitly set by plugin and theme developers, and its internal ones, in this layer, and a nice performance boost is gained. This doesn’t just work for API requests though, database queries that can run long, long PHP calculations, and more can all be stored in these super-performant structures.

But not all WordPress sites have this kind of caching available or enabled. To deal with that, WordPress can also store transients in its database (in the wp_options table). This is the #6 kind of caching — transients in the wp_options table. This is still a performance improvement vs making fresh API requests (for example) with every page rendered, but it’s less speedy than having a “dynamic cache” with a purpose-built in-memory cache like Memcache.

For long-running calculations or external API requests, either kind of WordPress transient storage is a big win. For more subtle cases, though, the use or non-use of transients will likely end up closer to a wash if the transients are simply stored in the WordPress database.

The Six Kinds of Caching

These are the six kinds of caching I know that exist as important considerations for a WordPress site:

  1. Storage of static assets in memory on the server, rather than disk storage
  2. Storage of static assets closer to your visitors, with a CDN
  3. Whole page caching via an external process, like Varnish
  4. Whole page caching with a plugin like WP Super Cache
  5. Partial caching of transients with an in-memory datastore like Memcache
  6. Partial caching of transients with the WordPress database

Each of them can have a big positive impact on your site speed. But each is different than the others, and some quite profoundly so. My hope is that you now feel able to understand, and pursue, the kinds of caching that’ll make your WordPress site as performant as possible. Happy hacking!

Image credit: Negative Space