Since a long time WordPress had a built in data caching system. Very few developers know about it or how it works. WordPress provides a very flexible data caching system i.e., its functionality can be customised and/or extended using plugins.
In this tutorial I will tell you how it works, where WordPress uses it and also what you as a WordPress developer need to know about it to create plugins and themes using this caching system.
WordPress Object Cache
WordPress Object Cache is a set of functions which allow you to store key-value pairs in memory. Key-value pairs are stored in memory so that retrieval can be very fast i.e., caching mechanism. So by default the data stored in Object Cache resides in the memory only for a duration of an HTTP request. Once the request is served the data is no more visible. So we can say WordPress Object cache is non-persistent by default. WordPress Object Cache also lets you categorise keys-value pairs in groups and lets you also set a expiration time for keys.
But WordPress does provide a way to make the object cache persistent across all HTTP requests. For this you need create a file named object-cache.php which needs to override all the functions of WordPress Object Cache. This overwritten functions can store the key-value pairs in any persistent caching storage system such as Redis, Memcached etc. There is no point of storing the key-value pairs in DBMS or Files because the sole purpose of WordPress Object cache is to store the key-value pairs in such a place from where keys-values pairs can be retrieved in almost no time(i.e., caching mechanism).
Keys has to be strings and values can be a array or any primitive type of data. Here are some examples of WordPress Object Cache provided functions:
//Add if not exists. If exists then ignore.
//Update if exists otherwise create
wp_cache_set("Full Name", "Narayan Prusty");
//Returns value of an key. Returns False if key doesn't exist
echo wp_cache_get("Full Name");
//Attach a Key to an Group
wp_cache_add("QNimate", "Narayan's Personal Blog", "Blogs");
wp_cache_add("QNimate", "Download Awesome WordPress Plugins", "WP Plugins");
//Retrieve 'QNimate' key from "WP Plugins" group
echo wp_cache_get("QNimate", "WP Plugins");
//Force some groups to be non-persistent.
$non_persistent_groups = array("Blogs", "WP Plugins");
//Delete complete cache
//delete a key
//delete a key from a group
//Add a key with expiration time of 5 seconds.
wp_cache_add("Job", "WordPress Developer", "", 5);
You can also check if the cache is persistent or non-persistent using the below code
//this returns true if an external caching plugin is installed. We are assuming that external plugins always provide persistent storage
Every WordPress API which uses MySQL also uses Object Cache to cache the data. While adding data they make a copy of the data in cache, while retrieving data they copy the retrieved data in the cache and while deleting data they delete data from cache also.
WordPress Options API
WordPress Options API is used to store key-value pairs. The key-value pairs stored using options API remains until you delete them. Options API maintains a options table in MySQL to make the options persistent.
WordPress options API tries to sync all options of the options table into object cache as much as possible. This is done to decrease MySQL hits and also retrieve key-value pairs faster.
While storing or updating a key-value pair using options API they are also stored in the object cache. So that they can be retrieved very fast. Similarly while retrieving a value of an key using options API the key-value is copied to the cache so that next time they can be fetched from cache instead of hitting SQL. Options API also uses object cache to store the keys which are not present in options table and had been queried for them earlier so that next time it doesn’t have to hit MySQL again unnecessarily. So we can say that options API tries to make a complete copy of the options table in cache.
Options whose autoload property is set to true is added to the object cache as soon as a HTTP request is made. By default all options have this property set to true.
If the object cache is not made persistent then obviously every HTTP request creates a new object cache session and syncing of object cache with options table is done for every HTTP request.
WordPress Transients API
WordPress Transients API also stores key-value pairs but with an expiration property set to expiration seconds.
In nutshell one transient is equal to two options i.e., one option for key-value pair and the other one for expiration key-value pair. Transients are stored in options table if persistent caching is not configured.
Transients API internally uses the options API to store transients if persistent cache is not enabled. But if persistent caching is enabled then it uses object cache directly.
Unlike options API which synchronises object cache with the options table to guarantee existence of data, transients API uses either options API(i.e, MySQL storage) or object cache. So the key-value pairs stored using transients API may get lost even before the time expires.
Transients API, Options API and Object Cache Together
Here is an image which shows how Object Cache, Options API and Transients API work together.
This diagram also shows how wp_load_alloptions() function is used to load all options with autoload property set to true into the object cache. And also it shows how they maintain a $notoptions array to keep track of previously queried not existent keys or rows to prevent unnecessary MySQL hits
WordPress Meta Data API
WordPress Meta Data API is used to store key-value pairs of data related to comments, users and posts. Whereas Options API and Transients API are used to store key-value pairs related to plugins and theme settings and data.
WordPress Meta Data API also works like Options API i.e, Meta Data API tries to sync all meta data of the meta data MySQL table into the object cache as much as possible. This is done to decrease MySQL hits and also retrieve key-value pairs faster.
If the object cache is not made persistent then obviously every HTTP request creates a new object cache session and syncing of object cache with meta data table is done for every HTTP request.
Every WordPress API which uses MySQL works like Options API in terms of using the object cache. They all sync their respective tables data to the object cache as much as possible. They all also maintain a key-value pair in object cache to keep track of previously queried not existent keys or rows to prevent unnecessary MySQL hits.
One unique feature Options API provides in terms of using the object cache is a autoload property for the keys.
Transients API works different then all other APIs as it uses either MySQL or Cache. It doesn’t do any sync. Whereas as all other APIs use the cache as middle layer while communicating with MySQL.