Today I run a test over my db to explore the speed difference between accessing a key from options, custom table & transients. I ran the test for 1000 times and following is the time taken to run 1000 get operations:
Keep in mind that the options table is used for both options and transients on most systems, and that table has been optimised, with indexes added. So it’s not a fair comparison
get_transient() 0.0245 seconds
get_option() 0.0068 seconds
simple select operation from Custom Table 0.65 seconds
This is also an unfair comparison, options with the autoload
option set, will be loaded in advanced in a single query early on. So get_option
is pulling from WP_Cache
, the option has already been retrieved.
TLDR: It’s not actually fetching the option, it was already fetched, it’s just pulling it from memory due to the autoload
option
I also checked that transient was not expired during this test.
This shouldn’t have an impact on a normal system on transient retrieval, after all it doesn’t know if it’s expired until it’s been retrieved.
So the question is, is get_option() faster than get_transient() or did I mess up something in my test?
It depends:
- On most systems, transients are stored using options, both involve a
get_option
call - Options with
autoload
set to true are all loaded in a single call at the start so they’re kept in memory, no queries happen after this - Object caching caches both autoloaded options, and transients
Is custom table delay due to options being cached default by WordPress?
Very possible, but how fast that select takes depends a lot on the query and table design
Also, is options also cached by different caching plugins like the transients?
Yes, WP_Cache
is used, which will store it in memory for the rest of the request. Caching plugins might persist these values for performance reasons.
Repeatability
These are all cached via WP_Cache
so the second time you request it, no DB is involved.
Variability and It Depends
This all assumes a common basis, but what about object caches?
Lets introduce a MemcacheD instance, or a Redis instance ( I STRONGLY recommend you do so if you have the option, HUGE performance benefits for well built sites, especially if you use them for page caching, unless you have something like Varnish setup )
Now we have a new situation:
- Now data is stored in RAM, and once it’s fetched from the DB it’s primed, and access times are dramatically reduced. Still slower than a variable, but significantly faster than a database query
- A lot of new data is stored in
WP_Cache
that normally isn’t. E.g.WP_Post
objects, post meta, etc WP_Cache
now persists across requests- MemcacheD etc can eliminate expired transients etc
So now transients and options have the same access cost. They were already close, but they’re now negligible and have more to do with the CPU load at the time the request was made.
So For Performance Should I Use Transients or Options?
While it’s a worthy question to wonder about, the answer is that the difference is negligible and within the margins of error
So stop micro-optimising, they’re the same storage medium, and this is not worthy of your time
- Use options if you need to store something that’s site wide
- Use transients to temporarily store things that are expensive to calculate so you don’t have to the next time
It is not worth your time to choose one over the other based on performance, there’s no meaningful difference.
There are far better things to do to optimise that give significantly greater savings, e.g. using taxonomies instead of meta in post queries, not using __not
style parameters, doing fewer things on the page, installing an object cache, lower posts per page, avoiding remote requests etc
What About A Custom Table That Will…
No, the options table is already well optimised, using a custom table will simply move operations outside of the WP Caching system, forcing you to write your own