Using Persistent Cache in WordPress (with APC)

Ever since WordPress 2.5, the WP Cache functions haven’t been persistent, so the cached objects are only available for the page load (or script run). This means that data stored in the cache resides in memory only and only for the duration of the request.

Upto version 2.5 we could have simply added define(‘WP_CACHE’, true) to the wp-config.php and we got persistent cache features. This is no longer the case and isn’t really very well documented.

The later versions need a Persistent Cache Plugin. I’m not a fan of some of the larger caching plugins like W3 Total Cache or WP Super Cache as they tend to add complexity and can cause other problems. Besides, as developers, we’re better off writing the code ourselves.

Before going any furuther its probably worth pointing out WordPress has two persistent caching methods.

The first method is the WP Transients API,

The second method is extending the existing WP Object Cache that is currently throughout your WordPress site already.

  • Extending this object is much more flexible
  • Can extend into APC, memcache or similar
  • Provides a fast cache for basic WordPress functions even before you write your own code

I use APC Op Code caching. Its simple to install and works very well out of the box. Its memory-based so faster than any implementation of the Transients API.
It can be as simple as a one line install.

[codesyntax lang=”bash”]
pecl install APC

See my other posts on APC.

If APC is installed, you need the Object Cache backend plugin. APC Object Cache Backend. Be sure to read the installation instructions, as this is not a traditional plugin, and needs to be installed specifically in wp-content/ not with the traditional plugin installer.

So, now we’ve got all the pre-requisites installed for some super fast, memory based caching fun. We can write some code.

The WP Object Cahce functions are kind of documentated on the Codex.

One of my clients, Toyota GB stores their videos on Vimeo. So each page load requires a Vimeo API call, this can get quite slow on an archive style page where the code may make 10 or more Vimeo API calls each time the page is loaded.

Lets call that API once per video and cache the results for everyone in the now persistent APC cache.

This is code block, I’ve added extra comments

$data = wp_cache_get($video_vimeo_id,'vimeo_cache_data'); // hang on, before going to vimeo.com, have we cached it?
 
if ($data == false) { // guess not, lets go get it and cache it
	echo('not cached. will cache');
 
	// Load in the oEmbed XML
	$data = curl_get(VIMEO_OEMBED_ENDPOINT . '.xml?url=' . rawurlencode('http://vimeo.com/'.$video_vimeo_id) . '&width=640');
 
	wp_cache_set($video_vimeo_id, $data,'vimeo_cache_data', VIMEO_CACHE_LIFETIME);
}
// no else, negative to cache, but we cached it for later. yummy.
else {
	echo('cached');
}
// convert cached/newly cached data into XML
$data = simplexml_load_string($data);

Theres a few constants in there,

define('VIMEO_CACHE_LIFETIME',31556926);
define('VIMEO_OEMBED_ENDPOINT','http://vimeo.com/api/oembed');

The code simply checks to see if the Vimeo Video ID is in the WP cache group “vimeo_cache_data“, if not it goes off and gets the data  from Vimeo.


Without any cache – 3.45 seconds


With WordPress running WP Object Cache and APC backend – 1.28 seconds

 Heres a quick peek at the APC back end status

 So by caching the API requests, we save a massive 2.17 seconds per page load!

Its worth pointing out this code only caches the Vimeo Video XML data, not the actual streaming video.

Not using Vimeo, here’s a simpler code block to get you started. This is not specific to Vimeo, you can cache any object or any external site request to save loads of time in your code.

$result = wp_cache_get( 'my_result' );
if ( false == $result ) {
	$result = $wpdb->get_results( $query );
	wp_cache_set( 'my_result', $result );
}
// Do something with $result;

 

Author: Kieran Barnes

Kieran is a PHP developer with 15 years commercial experience. Specialist in WordPress, CakePHP, CubeCart and all things PHP.

2 thoughts on “Using Persistent Cache in WordPress (with APC)”

  1. Where d o you put the vimeo cache code? In template? Functions.php?

    I really want to get this working because vimeo adds a long loading time to my wordpress site.

Leave a Reply

Your email address will not be published. Required fields are marked *