Overview of WordPress’ Transients API

There's a cool (and underused by plugins) API in WordPress: the Transients API. Transients are temporary options, ie options set with an expiration time. Anytime you're storing options and they have a short life span, you should use transients instead.

Disclaimer: I, for one, am totally underusing this API too, as it is rather new (it was introduced in WP 2.8) and I didn't update my plugins which could use it. Hopefully if you learn anything in this article, you will update your code :)

Transients functions

Basically transients are options, so their API is very similar to the Options API. The three functions you'll want to use are: set_transient(), get_transient(), delete_transient().

  1. // Save a transient to the DB
  2. set_transient( $transient_name, $transient_value, $expiration );
  3.  
  4. // Get value of a transient from the DB
  5. $value = get_transient( $transient_name );
  6.  
  7. // Delete a transient from the DB
  8. delete_transient( $transient_name );

Things to do or know:

  • Let WP do the dirty job: don't escape things for SQL, don't serialize arrays
  • Give your transients unique and self explanatory names. Prefix them just as anything else.
  • When you get_transient() and it has expired or has never been set before, the function returns false
  • In case you want to manually check the DB, saving a transient named 'ozh' adds two entries in the option table: _transient_ozh storing the value, and _transient_timeout_ozh with the Unix timestamp of the expiration date
  • Transients don't clutter the DB: when you fetch a transient value, if it has expired it is removed from the database

Using transients: an example

Let's make a simple plugin that displays the IPs of our last 10 visitors: this value is by essence temporary, and we will store it in a transient with a 3 minutes expiration.

The plugin will do the following:

  1. Store last 10 visitors' IPs in an array
  2. Get visitor's IP and check if it's in the array already

This whole simple plugin is just one function:

  1. // Get visitor IP, update and return list
  2. function wp_ozh_slvc() {
  3.     $ip = $_SERVER['REMOTE_ADDR'];
  4.    
  5.     $visitor_ips = get_transient( 'ozh_livecounter' );
  6.    
  7.     if( false == $visitor_ips OR !in_array( $ip, $visitor_ips ) ) {
  8.         // our transient has expired (or has never been set) or doesn't contain this IP
  9.         $visitor_ips[] = $ip;
  10.  
  11.         // just keep at most last ten entries
  12.         if( count( $visitor_ips ) > 10 )
  13.             array_shift( $visitor_ips );
  14.        
  15.         // store this transient with a 3 minutes expiration
  16.         set_transient( 'ozh_livecounter', $visitor_ips, 60*3 );
  17.     }
  18.    
  19.     return join( ', ',  $visitor_ips );
  20. }

And that's it. Now in a template PHP file such as sidebar.php just use the following:

  1. <?php echo 'Currently online: '.wp_ozh_slvc(); ?>
Download the plugin ozh-simple-live-visitor-counter.php.txt
(save as .php then put in your plugins folder)

As you can see the plugin is as basic and simple as it can be. Pushing things further you would widgetize the output for easier integration into themes, make smarter IP detection to check proxies and filter search engine robots out, implement a country detector based on the IP and display cute tiny flags, add an uninstall.php file with a call to delete_transient( 'ozh_livecounter' ); to make sure things are clean when uninstalled, and much more.

13 comments

  1. Ben

    Interesting API indeed. Would have been perfect for the cache of my Simple Flickr Photostream plugin if the set_transient had a callback on deletion.

    So when WordPress deletes the transient it also fires a function that would delete a picture file for example.

    Will keep it in mind for future plugin development, thanks Ozh.

  2. Elad

    Hi,
    In the example you expire the array after 3 minutes but don't you have to expire each ip at a time? In the current case, if you have a new visitor each two minutes the list will grow for ever.

    Am I missing something?

  3. Ozh

    Ben ยป It's easy, there's actions inside delete_transient() for this: add_action( 'delete_transient_simpleflickrstream', 'sfp_delete_picture' ). Look in the source of the function in wp-includes/functions.php

  4. Ozh

    Elad ยป ahah yeah totally. I'm dumb :) Will update this :)

  5. Ben

    Awesome, I did not look in the code, just went on the codex. I'll definitely use that for caching then, it's perfect. Thanks again.

  6. ma7aba star

    Very good
    I wrote about it in my blog
    http://www.ma7abah.com/blog/832.html

  7. R’phael Spindel

    Ozh,

    Thanks for this writeup, I just used the Transient API in one of my plugins after starting to use the wp_cache_* functions ( http://codex.wordpress.org/Function_Reference/WP_Cache ) then noting that they weren't persistent after WP 2.5 unless a pluggable caching mechanism was being used on the site. The Transients API will also be sped up if a caching plugin is in use as well.

  8. Gerry

    This is like Drupal's get_variables and set_variables function, but this one has expiration.

    I'm developing a WordPress site now and I believe I can use the Transients API for the project.

    Thanks Ozh!

  9. Andy

    Thanks for this. Now I understand what all these transients were about in my database.

    The options table in WP is getting rather bloated now though, isn't it?

    I wonder how efficient it is to have to search on option name to get a value many many times when generating a page and running many plugins.

    Of course caching can solve this problem for published pages.

    It should maybe be a rule that plugins may only have one option and this may be an array.

  10. justcoder

    I understand this is just example but you advice users to use this code. Also I saw such coding patterns in WP core too. And I can say this is total ignoring of concurency issues.
    Great example is cron emulation in wp. With high use lost scheduled tasks guaranted.

  11. Hikari

    OZH is the best! :D

    tnx a lot for your tutorial!

  12. nuwanda

    Is this like the thing in Codeigniter that allows messages to be sent on the nest page reload?

    Is there a way to clear it after the next reload? Be very handy for messages.

  13. Sagive

    Great Tutorial man and ther aint a lot of good examples out their using transient

    Thank
    Sagive

Comments are closed.