Speedo

Caching using the WordPress Transients API

The WordPress transients API offers a simple and standardised way of storing cached data for a defined amount of time in the database, after which it will expire.

SpeedoWhat is the WordPress Transients API?

Caching is an extremely important part of your WordPress development toolbox. If your site is running the same database queries again and again on each page load, you should take time to consider whether it’s really necessary. Is it really that important that your data is absolutely live to the second, or would it be okay to have this updated every hour? Serving from the transient cache makes your site load as quickly as possible without unnecessary database queries.

Why would I use transients instead of options?

WordPress savvy developers are probably aware of the WordPress Options API, which allows you to save custom name value pairs in the WordPress database, and are used frequently by plugins to store option settings. So why not just use this instead of transients?

The answer is that options do not have an expiry – they’re fixed and remain until updated or removed. Transients have a fixed expiry time and are removed automatically when the expiry time is reached. So if your data does not need to expire at any point, use an option. If it does need to expire, use a transient.

Another advantage of using a transient to store your cached data is that they’re sped up by using general WordPress site caching plugins such as W3 Total Cache, as explained by the WordPress codex entry for the transient API, whereas Options are not:

Also of note is that Transients are inherently sped up by caching plugins, where normal Options are not. A memcached plugin, for example, would make WordPress store transient values in fast memory instead of in the database. 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.

How to create and use a transient

Recently I created and launched international pricing on the Smart Insights site. This functionality uses the IP2Location service to determine the geographical location of the visitor from their IP address, and then serve appropriate prices and currencies depending on their location.

During initial testing, I noticed that validating the user’s location to output correct pricing was adding an unsatisfactory overhead to the page load, so I began to look how I could cache this information in a transient in order to reduce the number of calls to the geolocation service.

In order to do this, when a new visitor lands on the site, I check their IP, find their location, then set a transient containing the pricing and currency information;

// Check to see if a transient exists for the current visitor
$smartins_geo = get_transient('smartins_geo_trans_'.session_id());

if (!$smartins_geo) {
$user_geo = // do geo lookup and return pricing information here
//set_transient( $transient, $value, $expiration );
set_transient('smartins_geo_trans_'.session_id(), $user_geo, 3600);
}

A quick breakdown of the above;

  1. First I check to see if a transient already exists for this user using the get_transient function. Because I need to set the value against each site visitor the first time they visit the site, I’m appending their PHP session ID to the end of the transient name. This allows me to retrieve the transient for them on next page load.
  2. get_transient returns false if the transient does not exist – so I use this next to decide whether I need to set_transient for the user. If I need to do this, I then perform my look up using the IP2Location service – code to do this not included above – but it returns an array $user_geo with all of the pricing information. I then create the transient for the user.
  3. I’m using an expiry of 3600 seconds, which is an hour. You could set this to as long as you like – I’ve used an hour as it’ll be the maximum amount of time a user will get a certain price in case we decide to change the prices.

On next page load when this code runs, it will find the transient already exists for the current user and retrieve the pricing information directly from it.

I’d be really interested in knowing what other developers are caching with the WordPress transient API – let me know in the comments!

Update: 24th April 2013 – Turns out that WordPress doesn’t automatically remove expired Transients from the database – read “Does WordPress delete expired transients from the database?” for a simple solution.

Published by

Stu Miller

Web consultant and specialist, WordPress developer and PHP developer based in Leeds, UK. 15 years experience in architecting web sites and applications. Co-founder and Technical Director of SmartInsights.com, formerly the same of First 10 Digital

4 thoughts on “Caching using the WordPress Transients API”

    1. Hi Kenth – I think I answered that above – when you want to store any data that you don’t need to be completely live, but that you do want to expire automatically and refresh after a certain amount of time. Did you need any more specific info?

  1. I used this to gather a top 5 post with most views, but it seems is failing, I am using Mytop to watch the queries activities in the server and the query I added to transient still keeps executing, has anyone gone through this?

Leave a Reply