Do not use option nor transient!
This is about using the options database table, which again is a key value store, like the post metas, but for general data of your WordPress installation. It is also used by the transient functions. As always, it’s tempting to use it because of the ease of use, but you should really think twice about whether what you want to store should really go in there.
As always, please keep in mind that most WordPress installations do not suffer from the effects I will describe in this article. But maybe yours could be!
How does it work?
Using it is quite simple. With the following two lines you can set a value in the options table and get it right back.
update_option("option_key","value");
$value = get_option("option_key", "default value");
If you want to use transient, it is similarly easy.
set_transient("key", "value");
$value = get_transient("key");
This also saves an option, exactly as above, but with a _transient_ prefix for the key.
It is sooo easy. So let’s put something in there!
The Problem
There are optional parameters in both setter functions that many developers ignore. The following two update_option
calls are the same.
update_option("key", "value");
update_option("key", "value", null);
And what about the third optional parameter? This parameter is the autoload option. It accepts null
as it is the default value, "yes”
or true
to explicitly enable autoload, or "no”
or false
to explicitly disable autoload. If you ignore this parameter and leave it at null
, autoload will be enabled by default. Sounds good, right? Who wouldn’t want something to happen automagically? One less thing to do manually 🎉 ! Well no… But more on that later. First: What about set_transient
? Which optional parameter does it have?
set_transient("key", "value");
set_transient("key", "value", 0);
This time we can set an expiration time. If we do not do this, the default value 0
is used, which means that it will never expire. And if a transient does not expire, it will be saved as an option with autoload enabled, unlike expiring transients, which are not autoloaded by default 🤷♂️.
Why is autoloading a problem?
It is not, until it is.
To find the problem, let’s think about some cases for which developers could use options or transients.
- ✅ Saving some plugin or theme settings
- ⚠️ Caching a handful of small remote responses
- ⚠️ Saving an insane amount of plugin or theme settings
- 🚨 Caching an insane amount of small remote responses
- 🚨🚨 Caching a lot of very large remote responses
As you can see, the yellow and red flags come into play when it comes to a large amount of data being stored in this table. And the column with the option values is able to store a lot of data as it is of the text
type, which can store up to 65,535 (216 − 1) characters.
On each request, WordPress loads the autoload options with a single SQL query, which is I suppose the optimization that autoload is good for, and stores these values in a map for runtime caching. It’s a pretty good idea to reduce the number of queries to the database, but if you use any of the 🚨 labeled options, be prepared for out-of-memory errors at some point, which are usually very hard to debug.
Conclusion
Be aware of the optional parameters of the two setter functions and their default behavior. Only save options with autoload enabled if they are required on every request. If you intend to save or cache a lot of data, you should not use autoload. Rather consider using a custom table instead.