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

How was it for you? Let me know on BlueSky or Mastodon

(Please) Link to this page

Thanks for reading. I'd really appreciate it if you'd link to this page if you mention it in your newsletter or on your blog.

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...
27 May 2013

WordPress: 10 Years Young, What Does The Future Hold?

WordPress is now 10 years old. I started using wordpress 9 years ago – which means I joined the WordPress community early on. The reason I chose WordPress is simply because of the fabled 5 minute install process – I...
14 May 2013

Redesigning the WordPress Post Editor

Ghost is a project born from frustration with WordPress. Ironically it seems to be mostly WordPress power users who want to use it. The Ghost team – led by John O’Nolan – put Ghost on KickStarter last week and it...
17 Oct 2012

WordPress Social Network Aggregation

I really like the idea of a Tumblog – and even have one on Tumblr.com – but I don’t promote it anywhere. Conceptually it’s great – but I don’t like not having control over my content.What I would really like...
26 Aug 2016

My WordPress Wishlist

WordPress 4.6 has recently been released, and now plans are being made for WordPress 4.7. At the start of each new version the WordPress team ask for ideas and suggestions for areas people would like them to focus on. This...