WordPress sites that serve a large number of clients must have a continuous caching mechanism, not just for images and pages, but also for PHP objects themselves. Although WordPress already provides this mechanism through WP_Object_Cache, there are other solutions that offer greater possibilities. But first, let's explore what object caching in WordPress is and how it works in PHP.
Object Caching
As an object-oriented programming language, PHP uses the object paradigm to structure code. As a result, a WordPress website may consist of many different PHP objects that are constantly created, instantiated, and destroyed (by the memory manager). This creation and destruction of objects comes with a cost, especially if many such events occur. Additionally, many of them are often reused, as they represent core functionalities. In other words, each time the application needs them again, they have to be instantiated from the beginning.
Ideally, such objects should be cached rather than destroyed and recreated from scratch.
You can use the PHP function serialize()
to convert an object into a blob that can be stored in memory or on disk for later access. You can then calculate the hash number of the blob using the hash()
function and save both in the same way—hash as the key and the blob as the value. To call it back, you would use the previously saved blob’s hash number as the key. This way, you can convert anything (a string, number, object, array, etc.) into a version that can be saved in memory or on disk.
Example:
$serialized = serialize(array('test'));
You can also perform the reverse operation using the unserialize()
function:
$original = unserialize($serialized);
Essentially, there are three ways you can cache objects: using the native WordPress Object Cache, the Transients API, or external key-value storage provided by Redis or Memcached.
WordPress Object Cache
WordPress offers two caching APIs: the native WordPress Object Cache and the Transients API. They are identical, and although this might cause confusion, there is logic behind this that we will now explain.
The native WordPress Object Cache can store objects and primitives in cache, but not in a persistent manner. This means that the caching happens in memory and the cached objects do not persist beyond their defined lifetime. For this reason, you cannot share cached objects across different pages after they have been loaded. To enable this, you would need a plugin that extends WordPress’s functionality to handle persistent object caching.
On the other hand, the Transients API offers a more complete solution. You can store variables, arrays, and objects with a defined expiration date directly in the database, ensuring persistent object caching. However, a downside is that when a cached object expires, it remains in the database, unnecessarily occupying space. This means that you must monitor the database regularly to keep it clean from such objects.
WordPress can detect if you have implemented a custom object caching solution, and when it finds that this is the case, all calls to the Transients API are bypassed and routed to the WordPress Object Cache (which is why they appear identical).
Redis and Memcached
Redis is a key-value database that stores data in memory with occasional dumps of the database to disk and provides high availability in a cluster configuration. You can fine-tune the level of persistence to disk. The good thing about Redis is that if you restart the system, most of the cache memory will still be available because it will be loaded from disk into memory. In a regular scenario, after a server restart, the cache memory would have to be rebuilt, which typically increases load. With Redis, this doesn’t happen. Additionally, objects that have expired are immediately deleted from the database, so there’s no need for additional monitoring of expired objects.
Memcached is also a key-value store designed for caching objects, particularly for speeding up dynamic web applications and reducing database load. It is simpler to use than Redis and does not support dumping to disk because Memcached is multi-threaded, whereas Redis is single-threaded.
Because it is specifically designed for object caching in web pages and uses an in-memory database, it provides a fast solution for caching objects. On the downside, as we mentioned earlier, if the server is restarted, the cache memory will be wiped out, and until it is rebuilt, there will likely be increased load on the database. This is a disadvantage of the system, but it is still sensible to use it as a caching system for your website.
Conclusion
As we’ve seen, both solutions have their advantages and disadvantages. Whether you decide to opt for any of them depends primarily on the number of objects your application/website has. If it’s a small number of objects (say, a dozen), you likely won’t notice much of a benefit or acceleration from using these solutions. However, if the number reaches the hundreds, you could benefit from implementing one of the mentioned solutions. In any case, now you know more about how object caching works in WordPress.