- Wordpress part of transient handling is solid, everything is pretty precise
- Transients use object cache instead of data store for non-default implementations
- It means that some back-end cache systems get rid of cache that hasn't been accessed recently
- Bottom line: it's not WordPress fault, it only depends on how your back-end cache is set up
You could get transients to be more precise but it requires back-end cache tweaking which I do not recommended if you don't know what you're doing, too much cache could have opposite effect.
But even then, don't assume that it is 100% precise.
From WordPress Codex:
Everyone seems to misunderstand how transient expiration works, so the
long and short of it is: transient expiration times are a maximum
time. There is no minimum age. Transients might disappear one second
after you set them, or 24 hours, but they will never be around after
the expiration time.
You should always have a fall back method.
Why is it happening?!
WordPress only invalidates transients when attempting to read them
(which has lead to garbage collection problems in the past). However,
this is not guaranteed for other backends.
Transients use the object cache for non-default implementations. The
really important part to note here is that the object cache is a
cache, and absolutely not a data store. What this means is that the
expiration is a maximum age, not a minimum or set point.
One place this can happen easily is with Memcache set in Least
Recently Used (LRU) mode. In this mode, Memcache will automatically
discard entries that haven’t been accessed recently when it needs room
for new entries. This means less frequently accessed data (such as
that used by cron data) can be discarded before it expires.
Read more from this article, it is very well explained.
There are plenty of different systems but here's an example how MySQL database caching generally works. Im not sure how helpful it is to understand transients caching but I guess it couldn't harm.
- Data from each different query gets cached
- Each cached data gets a value (more complicated query
== higher value)
- These values gets decremented (like a countdown timers if you will)
- Caching system checks these values in intervals
- If any of these values reaches to zero, that cache gets destroyed
- If same query is ran again, value goes back to initial value
So.. What could you conclude from that? There's no point to set transient that are:
- Too simple
- Not frequently used
Because these gets destroyed very quickly in most cases. I hope this gives you a clearer picture how caching generally works. It prioritizes frequent and complicated over simple and rarely used data.
Note: there's a lot of generalizations in cache explanation to make it easy to follow and understand.