Transients And Docket Cache
Transients are one of the most used features in WordPress, and one of the most confusing once an object cache is involved. Where do they go? How long do they last? Why does a plugin sometimes behave differently? This post answers those questions for Docket Cache.
What a transient is#
A transient is a value that a plugin saves for a limited time. It is a simple way to remember the result of slow work, such as a call to another website or a heavy database query.
set_transient( 'my_plugin_feed', $feed, HOUR_IN_SECONDS );
$feed = get_transient( 'my_plugin_feed' );
if ( false === $feed ) {
// Not there any more, so build it again.
}
A plugin can save a transient for one site, with set_transient(), or for a whole multisite network, with set_site_transient().
Where transients go#
Without an object cache, WordPress keeps each transient in the wp_options table, as two rows. One row holds the value, and the other holds the expiry time.
With Docket Cache active, WordPress sends transients to the object cache instead. Docket Cache saves each one as a cache file, in the transient or site-transient group. WordPress then no longer reads transients from the database at all.
The move from the database#
That raises a question. What happens to the transients that are already in the database when you turn Docket Cache on?
Docket Cache copies them into the cache once. When its drop-in file is installed or updated, it copies up to 1,000 transient rows from the database at the end of the first request. Then it deletes the rows that have expired or that have no expiry time. Rows that are still valid stay in the database.
Our post What Went Wrong In 26.04.10, And How 26.04.11 Fixed It explains this step, and a bug it had in one release.
The garbage collector also tidies up the database. On each run, it deletes expired transients that are still in the database. WordPress itself only does this once a day.
How long a transient lasts#
- With an expiry time, a transient lasts until that time.
- Without an expiry time, Docket Cache keeps it for 1 day. Without an object cache, WordPress would keep it forever, and load it on every page.
- No cache file is older than the maximum age, which is 4 days by default (
DOCKET_CACHE_MAXTTL). The garbage collector removes older files, so a transient set to last a week may be gone after 4 days.
There is one more difference. Docket Cache does not save an empty string or an empty array as a transient, so these read back as false.
None of this breaks a well-written plugin. A transient is a cache, and WordPress has always said that it can disappear before its expiry time. A plugin should always check for false and build the value again, as in the example above.
When to keep transients in the database#
Some plugins do not use transients well. They save very large values with no expiry, or they assume a transient is always there. A few call PHP's unserialize() on a transient themselves, and crash with an error like this one.
Fatal error: Uncaught TypeError: unserialize(): Argument #1 ($data) must be of type string
For these cases, Docket Cache has an option called Retain Transients in Db. Turn it on in Docket Cache > Configuration, or add this line to wp-config.php.
define('DOCKET_CACHE_TRANSIENTDB', true);
Transients then stay in the database, as they would without an object cache. A few WordPress transients still use the cache by default. These are doing_cron, update_plugins, update_themes and update_core. You can change this list with DOCKET_CACHE_IGNORED_TRANSIENTDB.
We suggest you only turn this option on when a plugin needs it. For most sites, transients are faster in the cache. If a plugin crashes with the error above, also ask its author to use the WordPress function maybe_unserialize() instead of unserialize().
Clearing transients#
To clear only the transients and leave the rest of the cache, run this command.
wp cache flush:transient
In the admin, turn on the Additional Flush Cache Action Button option in Docket Cache > Configuration. A Flush Transient Cache button then appears on the same screen.
This is useful when a plugin shows old data after you change its settings, or when you test a plugin that builds its data in transients.
For plugin authors#
If you write plugins, these habits make your transients work well with any object cache, not only Docket Cache.
- Always give a transient an expiry time.
- Always check for
false, and build the value again when it is missing. - Do not save very large values, such as whole pages of HTML, in one transient.
- Use the WordPress functions
maybe_serialize()andmaybe_unserialize(), not PHP'sserialize()andunserialize(). The WordPress functions only change a value when they need to, so a value that is already unpacked is left as it is. - You can also save an array or an object as it is. WordPress and the object cache take care of storing it.
The Data Storage page in our documentation explains how Docket Cache stores transients in detail.