WordPress offers an easy and highly extensible caching system. Many functionalities use it in the background. Moreover, you can implement it easily into your own code. Smashing Magazine wrote a very detailed post about several WordPress caching methods. Complex data queries and other expensive calculations don’t need to be executed each time with the flexible WordPress caching system. Once cached, they can be returned in future queries blazingly fast. In this blogpost, I want to give an introduction into WordPress’s caching system. I also present an Inpsyde solution which unifies the WordPress caching process.
Introduction into the WordPress Caching System
Normally, elements in the WordPress cache have no persistence. Hence, they are only cached for a single page view and need to be created anew for each request.
The only exception are WordPress’s transient functions which write cached elements into the database. You can create a timeout for these transients after which they have to be regenerated. Unfortunately, many database accesses cause performance problems and orphaned transient datasets are a recurring annoyance which bloats the database little by little.
The good thing: If you want to, you can replace the entire caching logic. With a “wp-content/object-cache.php” file – or rather a caching plugin creating such a file – you can connect many external tools like:
Depending on what your server offers, you have several options to get a “persistant object cache”. And with it you can greatly improve your WordPress performance because cache elements can now outlast a page view and are available directly for the next time. This is one of the most important mechanisms in terms of website performance.
WordPress Caching in daily life
In the daily life of our agency, we sometimes face the situation that not all systems to run the same site on are exactly the same. The live system might run Redis, the internal test system might only offer APCu and a developer might not have an external caching on his local environment at all. For the deployment of WordPress websites, this would mean deploying a different caching solution for each server. This is confusing and not elegant.
Situations like these are not always avoidable and even when they are, you can surely understand that we wish to have standardized tools for recurring requirements. It’s simply not practical to juggle twenty different object-cache.php files and have different things installed everywhere.
The Caching Standard PSR-6
In the big PHP world, people saw that problem as well. That’s why a standard named PSR-6 http://www.php-fig.org/psr/psr-6/ has been created. It defines an interface by which different caching backends and clients can work completely independent from each other. In other words: When using a PSR-6 solution, you don’t need to think about whether Memcached or Redis works in the background. With “Stash” ( http://www.stashphp.com/ ), a library exists that supports all imaginable cache-types and caching systems and even some further features. I want to describe two of them in the following.
Regeneration Before Expiration / Stampede Protection
You can regenerate cache items even before the cache reached its end of life, making new data available immediately. Additionally, you avoid that several users have to regenerate the same cache. When regenerating complex elements in extreme load scenarios this can lead to a total crash as each new page visit starts the heavy regeneration process again and therefore needs even more resources.
Hierarchal Cache / Group Invalidation
Stash allows arranging its caches like a directory structure. Hence, when deleting a parent node, you also invalidate all sub-elements. This requirement appears over and over again, is not very easy to implement in WordPress and has therefore led to adventurous, but billiant solutions: https://www.tollmanz.com/invalidation-schemes/
The described requirements in our daily life and the possiblities with Stash spawned the idea to connect Stash with WordPress. The result: “WP Stash” is available on GitHub. It’s a MU plugin and therefore always runs and cannot be deactivated.
You configure WP Stash via the wp-config.php. At the moment, it’s possible to define a CacheDriver and its parameters. For example you can define that Redis is used and which data base shall be contacted. You can use all drivers Stash provides, more information here: http://www.stashphp.com/Drivers.html
Here is an example how to configure WP Stash for APCu:
define( 'WP_STASH_DRIVER', 'Stash\\Driver\\Apc' );
define( 'WP_STASH_DRIVER_ARGS', serialize( array('ttl' => 3600 ) ) );
If you didn’t define a driver, WP Stash uses an in-memory-cache as fallback solution which behaves just like WordPress’s default caching methods. Therefore it has no persistence.
With the help of WP Stash, help we can deploy the same website on serveral different systems. All we need to do is to connect the website with the particular caching backend via the configuration done in wp-config.php. Additionally we get some features and improvements in terms of stability.
Due to the limited interface of wp_cache_* functions, not all the additional features of Stash can be adressed directly. That’s why we are working on a client library which adds these functions to the well-known WordPress caching and optionally avoids the detour via WordPress and works with WP Stash directly.