Intelligent caching of changing data with the WordPress Transients API
Recently I built a shortcode for displaying data from the Android Market. You can see it in action on Android and Me. To make the magic happen, I query the AppAware API for a couple key bits of data, mainly the app icon, title, developer name, etc.
After a while, I realized that even without a rate limit being imposed by AppAware, some of my calls were failing. To lighten the load, I turned to the WordPress Transients API, a super simple way of saving (or caching) data for later use. Because saving a transient stores the data locally, you won’t need to make as many external calls, which is good for you and for your API partners.
What is the Transients API?
If you’re an experienced developer and you’re familiar with the concept of caching, you can probably skip this section. The code samples are below. But if you don’t know a thing about saving data locally, WordPress says: the Transients API offers a simple and standardized way of storing cached data in the database temporarily by giving it a custom name and a timeframe after which it will expire and be deleted. Also of note is that Transients are inherently sped up by caching plugins, where normal options are not.
For this reason, transients should be used to store any data that is expected to expire, or which can expire at any time. Transients should also never be assumed to be in the database, since they may not be stored there at all.
This makes transients the perfect solution to storing data you would otherwise call from a 3rd party. Ideally, when you need the data, you’ll first check to see if the transient exists. If it does, you use that data. If it doesn’t, you call for a fresh version of that data, when you then not only use, but save and timestamp for later use. Sound simple enough?
Setting and getting transients
The main functions we’ll be using are, predictably, set_transient and get_transient, both of which couldn’t be simpler. To get started, let’s look at the absolute first step, saving a transient. If you’ve ever saved meta data using update_post_meta or update_user_meta, this should look totally familiar to you.
The function accepts three arguments, all of which are pretty straight forward. First, $transient is the name of the actual piece of data to be stored. This is the unique ID by which you'll call the data later, so make it good. The $value is the actual data being stored, aka the payload. You'll use $expiration to set the time limit on this transient, in seconds. When the time expires, so does the data.
Once you've got some data saved, you'll likely want to call it in your templates. Getting a transient is even easier than setting it:
Here, again, $transient is the unique identifier of the data your looking for. There isn't much to explain here. When you call the transient, if the time limit hasn't expired, you'll have the data to do as you please. If the data has expired and you still need it, things get a tiny bit more complex, which brings us to my next point...
Putting it all together
Our sample case will be displaying our Klout score, via the Klout API. Like I said, this Transients API should be used for time-sensitive data, data that changes or that needs to be refreshed at a reliable interval. And while we're discussing use, it doesn't have to be external data, you could use it to store just about anything. We're just going the API route during the example to score some bonus points.
I've heavily commented the code below, but the basic path goes like this. First, we'll attempt to call the transient. If the data exists, our job is done and we use it. If the data doesn't exist or has expired, we'll call for a fresh copy from the Klout API, which we'll then save and immediately use.
The main check is if( !$klout ), which, of course, checks to see if the value $klout is set, which we attempted to do with get_transient. If it is not, we know we need to fetch a fresh copy of the data and save it (set_transient). Since we're using a private API, you'll need to replace [API key] with your personal API key (duh).
If you wanted to get fancy, you could always work in the delete_transient function, but since these things expire with time I'm content to be the lazy type and just let decay do its work.
Go forth and cache
Equipped with your new army of drifter data you're ready to speed up page loads by reducing reliance on often slow external API calls. And if you're dealing with a rate-limited API, caching is a necessity, so you might as well do it with a supported WordPress API.
DATE27th January, 2012