WordPress caching, Part 2

As I mentioned in WordPress caching part 1, WordPress has built-in caching that can be hooked into by plugins such as W3 Total Cache and Batcache (developed by Andy Skelton who is employed by Automattic).

In this article I am going to explain how I make use of WordPress internal caching – also know as the persistant cache – to speed up my site (and in turn Elemental).

What the persistant cache does is store the data you tell it to in a variable, so that the next time you use the data on that page you don’t have to touch the database. If you have software like Memcached and Batcache installed then the data will also be saved to memory – which means future page loads will skip the database entirely. There’s some documentation on the WordPress caching on the codex.

This might sound like a really obvious thing to do but surprisingly few developers make use of it.

As an example in Elemental I created a simple widget that grabbed a list of recent posts by a specific author. Before I learnt about the post caching I was doing 1 mysql query to grab a list of posts and then running the standard WordPress ‘loop’, which was then doing an extra query per post to get the relevant post information.

The problem was it didn’t matter what information I requested in my original database query, I would end up doing 6 queries (1 to get the list of posts, and then 1 for each of the 5 posts). Once I plugged in the caching the number of queries instantly dropped back to 1.

To use the caching you have to use the function wp_cache_add. Keep in mind that you should query all the post data in the table, even if you only need the title, this is because the cache may be used elsewhere on the page, and missing data will mean more data will need to be grabbed, which negates any savings you made.

So – what I started with was something like:

	$sql = 'SELECT ID, post_title FROM ' . $wpdb->posts . '
		WHERE post_author = ' . $primaryPostData['author'] . '
		ORDER BY post_date DESC LIMIT 0, ' . $postAmount;

	$posts = $wpdb->get_results($sql);
	if ($posts) {
?>
	<ul class="authorPosts">
<?php
		foreach ($posts as $p) {
?>
		<li><a href="<?php echo get_permalink($p->ID); ?>"><?php echo $p->post_title; ?></a></li>
<?php
		}
		wp_reset_query();
?>
	</ul>
<?php
	}
?>

… and after the caching I had the code:

	$sql = 'SELECT * FROM ' . $wpdb->posts . '
		WHERE post_author = ' . $primaryPostData['author'] . '
		ORDER BY post_date DESC LIMIT 0, ' . $postAmount;

	$posts = $wpdb->get_results($sql);
	if ($posts) {
?>
	<ul class="authorPosts">
<?php
		foreach ($posts as $p) {
			wp_cache_add($p->ID, $p, 'posts');
?>
		<li><a href="<?php echo get_permalink($p->ID); ?>"><?php echo $p->post_title; ?></a></li>
<?php
		}
		wp_reset_query();
?>
	</ul>
<?php
	}
?>

Note: This example is hugely simplified and won’t work as a copy and paste job. It’s just outlined to show the differences between the 2 methods.

Traditionally the first example would be considered quicker. You are requesting just the data you need (only 2 fields) and then displaying it. However since the post data is not in the query cache the usage of the ‘get_permalink’ function means that additional database queries have to be made to get the permalink shortcode.

In addition, any time you use WordPress built in functions to get the data for this post again, they will already be in the query cache.

Usage

Using the function is simple. In my example above you have to pass an array of the post data, the post id, and the cache type – to be used as a key for retrieving the data later.

<strong>wp_cache_add($key, $data, $flag = '', $expire = 0);</strong>
param: int|string $key The cache ID to use for retrieval later
param: mixed $data The data to add to the cache store
param: string $flag The group to add the cache to
param: int $expire When the cache data should be expired

You can read up more on the wp_cache functions and their usage on the official codex page.

Note: if you are using the query_posts command, or pretty much any other built in WordPress function, then the caching will be taken care of for you. It will also, where possible, make use of any data you save to the cache as well

Let me know what you think on Mastodon, or BlueSky (or Twitter X if you must).

WordPress News

The latest WordPress updates from the WPBriefs Podcast.

Related Posts

08 Apr 2010

WordPress Caching, Part 1: The Basics

Caching (on the internet) is the act of storing computationally expensive calculations in a way that can be recovered very quickly with the smallest possible impact on the server.Or, in short, ‘speeding stuff up’.In this series of posts I will...
30 Mar 2010

10 WordPress query_posts tips you probably don’t know

I have written a really brief query_post tutorial before, and it did quite well, but both WordPress and my own skills, have advanced considerably since then. So I thought it would be interesting to revisit the query_posts command and see...
28 Aug 2008

WordPress 2.7 and Crazyhorse

Last weekend I spent a few days away from WordPress and work in general to spend some quality time with the girlfriend. When I got back and updated my local copy of WordPress (via svn) I was surprised to see...
11 Apr 2013

WordPress Query: Exclude Posts With No Featured Image

So – I make WordPress themes – lots of them 🙂Something that’s bugged me for a while is that I can’t easily use the WP_Query to select posts with featured images. This isn’t functionality that’s needed that often – but...
22 Apr 2010

How to Build the Perfect WordPress Sitemap

I was recently asked how I built the sitemap on Binary Moon so I thought I would share the code. The sitemap layout is actually one of the many custom page templates available in my WordPress theme, Elemental – however...
13 Mar 2018

WordPress: The Difference Between is_home and is_front_page

When making WordPress themes there’s 2 functions that are really handy. is_home and is_front_page. I use them all the time in both themes and plugins. But I can never remember the difference between them.is_home vs is_front_pageOn the surface they are...