A Guide to Transients in WordPress
As a WordPress developer, you probably already know how important performance is to a successful website. However, understanding transients in WordPress and how they’ll help you optimize your projects can be a little tricky.
Fortunately, when you break them down, transients aren’t all that difficult to understand. As long as you keep a few key guidelines in mind, you should be well on your way to incorporating them into your next WordPress plugin.
In this post, we’ll provide an overview of what WordPress transients are, along with how and when to use them. There’s a lot of ground to cover, so let’s get right to it!
What are WordPress transients?
In order to understand transients, it’s helpful to have some basic knowledge of caching and Application Programming Interfaces (APIs).
Caching webpage data is essentially a way of temporarily saving a website’s data so that if there are multiple requests for the same data, the site doesn’t have to re-run MySQL or PHP. This can save seconds of time and reduce server load.
The idea is to keep data around temporarily, hence the word “transients.” The Transients API is similar to the WordPress Options API.
You give data a name and a value—which can be complex, like a multi-level PHP array—and it stores the data. Later, perhaps even on a different request, you can retrieve that data using its name. The difference is that data in the Options table will stick around forever. That is, you can store data, and three years later, it will still be there.
Every transient is made up of three parts:
- $transient. This is the string used to identify your transient and call it up. It’s also referred to as the transient’s ‘key’ or ‘name’.
- $value. This is the information being retrieved via an API. A transient’s value can be an object, an array, a number, or a string.
- $expiration. This is how long a transient stays in your database, before it’s deleted and you have to access the information you need through the API again.
On the surface, that’s all there is to WordPress transients. However, in order to use them properly, there’s more you need to know.
Transients data will not stick around, however. That’s the point! You can request the data, and find that it’s missing in one of two ways. First, when you store the data, you specify an expiration date. For example, you could say “store this for three hours.” So if you request it after four hours, it will be missing.
The second way is that piece of data is allowed to simply vanish, at any time, for any reason. That sounds odd I know! What’s the point of storing the data if you can’t count on it?
The point is that the storage is a request which WordPress will attempt to honor, but because of this flexibility, it’s possible to use different kinds of implementations for transient storage, and that means it’s possible to use different, advanced technology to make transients extremely efficient, and operate properly even in a multi-server clustered environment.
Because of this “vanish at any time” thing, you generally use transients for a cache. That is, if you need to compute something that takes real time, like a slow MySQL query, or retrieving data from an external source like someone’s Twitter or RSS feed, you can store the computed data in a transient, knowing that if it goes missing it’s always possible to recreate it.
But in the usual case—when it does NOT go missing—you have the data quickly without having to recompute.
The benefits of using transients on your WordPress site
As we mentioned earlier, the primary benefit of transients is that they improve website performance. Here’s a rough outline of how that works, using the Google Site Kit plugin as an example.
When the plugin is activated, it uses an API to display data from platforms such as Analytics and Search Console in the WordPress dashboard. Without transients, WordPress would have to retrieve this information from each tool every time you viewed your Site Kit dashboard:
Instead, Site Kit includes transients that cache data from Analytics and Search Console. They are stored for one day (or one hour if the platform returns no data).
Every subsequent time you access your Site Kit dashboard, WordPress can quickly retrieve the stored information from your database instead of having to call the API again. When the expiration period runs out, the old data is deleted.
This means you don’t have to wait for your results to load every time. This comes in handy in a variety of situations, such as showing social media share counts for your posts or displaying a newsfeed.
Drawbacks of using transients on your WordPress site
What gets you into trouble with Transients are the different, and hard to reproduce, behaviors you get when your plugin/theme runs under different transients implementations. Different transients implementations means you will ONLY run into problems in certain configurations with certain types of sites, and never in others.
As a developer, if you’re not aware of this pitfall and aren’t coding accordingly, you’ll think your code is sound, but in fact it will break in the field, and you won’t even know how to reproduce it!
When to use WordPress transients
Transients are deleted from your database once they reach the end of their expiration period. For that reason, you only want to use them for information that is continuously re-created.
Additionally, although they can improve your project’s performance, transients are best reserved for large queries and remote calls. If it will require more code to create a transient than it will to simply make a fresh request for the resource each time it’s needed, you’re better off going without.
Managing WordPress transients
If you want to easily see and manage the transients that are currently at work on your WordPress site, you can install the Transients Manager plugin:
It provides a complete list of transients, which you can find by navigating to Tools > Transients:
Here you can see all three transient elements we listed earlier – the key (name), value, and expiration period. You can edit any of these features by clicking on the Edit link:
You can also delete transients individually or in bulk.
Basic operations used in transients
When it comes to coding your own transients, there are three basic operations you’ll likely need to use. We’ve outlined each of them below, continuing to use Site Kit as an example.
1. Setting transients
Creating or ‘setting’ transients is the process of defining the key, value, and expiration period, and applying that information to the relevant data. To do so, you’ll use the following format:
Set_transient (‘key’, $value, expiration_period)
Here is the code used in Google Site Kit to set the transient that stores analytics data:
// Cache "data found" status for one day, "no data" status for one hour.
set_transient( $transient_key, (int) $has_data, $has_data ? DAY_IN_SECONDS : HOUR_IN_SECONDS );
}
return (bool) $has_data;
}
}
The transient key is googlesitekit_analytics_has_data (defined earlier in the code), the value is $has_data or $has_data ?, and the expiration period is one day or one hour (depending on the value).
2. Retrieving transients
Retrieving transients is a little more complicated. First, you need to use a function to request the necessary data. Then you’ll check to see if it has a corresponding transient that should be loaded, instead of making a new API request.
The result might look something like this:
function some_function(){
$transient = get_transient(‘key’);
You’ll then need to either return the transient, or delete the expired data and make a new call to the source. Finally, you have to set the transient after you’ve returned the new data, so it will be stored again until the expiration period runs out.
In Google Site Kit, that looks like this:
/**
* Checks whether Analytics data exists for the given URL.
*
* @since 1.4.0
*
* @param string $url The url to check data for.
* @return bool
*/
protected function has_data_for_url( $url ) {
if ( ! $url ) {
return false;
}
$transient_key = 'googlesitekit_analytics_has_data_' . md5( $url );
$has_data = get_transient( $transient_key );
if ( false === $has_data ) {
/* @var Google_Service_AnalyticsReporting_Report[]|WP_Error $reports Array of reporting report instances. */
$reports = $this->get_data(
'report',
array(
'url' => $url,
'metrics' => array(
array( 'expression' => 'ga:users' ),
array( 'expression' => 'ga:sessions' ),
),
)
);
if ( is_wp_error( $reports ) ) {
$reports = array(); // Bypass data check and cache.
}
foreach ( $reports as $report ) {
/* @var Google_Service_AnalyticsReporting_Report $report Report instance. */
$report_data = $report->getData();
/* @var Google_Service_AnalyticsReporting_ReportData $report_data Report data instance. */
foreach ( $report_data->getTotals() as $date_range_values ) {
/* @var Google_Service_AnalyticsReporting_DateRangeValues $date_range_values Values instance. */
if (
isset( $date_range_values[0], $date_range_values[1] )
&& ( 0 < $date_range_values[0] || 0 < $date_range_values[1] )
) {
$has_data = true;
break 2;
}
}
}
This code should then be followed by the snippet we included in the previous section for setting transients.
3. Deleting transients
In some cases, you may find that you want to remove a transient. For instance, if you want to always see the most updated analytics in Google Site Kit, it would be better not to cache data (although we’re not recommending that you actually delete Site Kit’s transients).
Otherwise, the plugin will show the same results throughout the day, even if you’ve had new visitors. Since the transient lasts for 24 hours, the data you view in the afternoon will simply be a cached version of the data you loaded in the morning.
The easiest way to delete transients is by using the Transients Manager plugin. However, if you want to use code instead, you can put the delete_transient() function to use. All you need is the transient key:
delete_transient(‘key’);
However, you’ll have to repeat this for each transient you wish to delete.
Transient expiration: How does it work?
Transient expiration periods can be expressed in a few different ways. The simplest two options are:
- In seconds (set_transient(‘key’, $value, 86400))
- Using WordPress Time Constants (set_transient(‘key’, $value, DAY_IN_SECONDS))
Alternatively, you can also set never-expiring transients. This can be useful in situations where you want to keep transient data the same, until you manually delete and reset the cached information.
Creating never-expiring transients is quite simple. Simply leave the expiration parameter in the set_transient function blank, or identify it as zero.
Understanding the WordPress Transients API
The WordPress Transients API is simply the means by which information is cached in your site’s database. It enables all of the related operations we’ve discussed throughout this post, including setting, getting, and deleting transients.
In other words, the Transients API is just the part of WordPress’ core that lets you use transients.
The two most common implementations of the Transients API backend:
- The one built into WordPress, and therefore the most common by far. Transient values are stored in the wp_options table just like regular options. With transients, an additional option is stored to hold the expiration date. When a transient is accessed, WordPress pulls the expiration date first. If it’s expired, WordPress deletes both options from the table, thereby “cleaning up” the data, and pretends the data was never there. If it’s not expired, it grabs the content from the options table.
- Memcached. Memcached is a very simple yet efficient and reliable server-side software designed to do exactly what the Transients API is supposed to do — store data based on a key, which expires at a given time, and which can vanish at any time if it needs to.
Using memcached instead of WordPress Transients has two special benefits, which is why we automatically preconfigure it for you here at WP Engine. We’ve got your back
i. Memcached is 10x-100x faster at storing and retrieving values than WordPress Transients, which is especially interesting since the point of transients is to cache data to increase the speed of a site.
ii. Memcached sets the maximum amount of space it will take up with data (e.g. 64MB of RAM), which means if a site stores too much data at once, it will automatically throw out old data, and therefore never runs out of space. But the built-in WordPress Transients will store an arbitrary amount of data in the options table.
Applying transients in your development
Suppose you’re reading and writing the same Transients key repeatedly, and suppose it’s 1k of data. In that case, both Memcached and the WordPress Transients will do just what you expect them to, and both will take up about 1k of space (either in the options table or in memcached).
Now suppose you’re reading and writing different Transients keys, different for each browser session. In short, what if you’re storing user-session data in Transients?
This makes sense on the surface. Session data shouldn’t last forever, and you don’t want to bother with special database tables. Besides that, many hosting companies don’t allow PHP sessions, so this really is the next best thing. It’s even fast and multi-server.
Here’s where the differences appear. With Memcached, and with a site with low traffic, this method appears to work. The values last for a while, then get deleted as they expire.
However, if the server is heavily loaded, the amount of session data the server needs to store will exceed the space available in memcached, and therefore you’ll start losing session data sooner than you thought.
And if you didn’t test in this exact, heavily loaded, environment, you’d never know that. In general, these environments end up filling memcached so quickly that effectively memcached is disabled because it can never hold onto data long enough to be useful. You effectively don’t have a Transient API cache at all!
But with the WordPress Transients, you get different but still very undesirable behavior. Because the values are written to the database, not a fixed-sized block of RAM, they all stick around. Which means even with the heavily-loaded site, you still have your session data. Awesome!
Or so you thought. Because what isn’t said in the Transient API is what happens when you use unique keys like sessions.
With the built-in method, the options table fills up indefinitely! WordPress’s “old data clean up” only operates when you request the key (as we covered earlier). If you just leave the key, it’s left in the options table, forever. There’s no separate process that cleans these up!
We’re not only aware of this problem, we want to help out our customers who might be running code that doesn’t understand this. That’s where the “managed” in Managed WordPress comes in!
Every night, we have an automated process to look through your options table for expired transients, and delete them (both the data and the expiration date item). Boom! They’re gone, and you don’t have to worry about them.
So that’s awesome that we do this, but as a developer of a general plugin or theme which is supposed to operate properly on any hosting environment, you can’t do this in all the potential environments your plugin or theme might be deployed, and you want to make sure you’re providing your users and customers with the most optimized code possible.
However, now that you know how Transients can go awry, it might be an awesome idea to take a look and see how you can make your code more efficient.
Chances are, if you’ve read this far, you like optimizing your code, and this blog post may throw down the gauntlet for you and motivate you to re-write some things to be more scalable!
Do more with your WordPress site
As a WordPress developer, providing your end users with access to remote data while maintaining fast performance is key. WordPress transients can help you accomplish just that.
However, it doesn’t hurt to get a little extra help from lightning-fast hosting and professional developer resources. Whether you’re new to coding or a seasoned pro, we’re ready to help. Check out our plans today!