Statamic's Caching Levels Explained
Modern web applications are very complex systems, which is also true for your Statamic site. It might be simple to use and extend, but in the background there are a million things that need to happen before a visitor can read your latest blog post.
Countless data retrieval and processing tasks need to be completed, requiring computing power and time. So a simple page load could take several seconds to finish and put a lot of strain on your server.
So instead of doing all that on every request, the data is only retrieved and processed once, and then stored in a way that makes it easily accessible for the next request - commonly referred to as caching.
Laravel's Application Cache
Our favorite PHP framework always tries to make life easier for developers, and the same is true regarding caching. Laravel has you covered and provides several options where to store your cached data - from writing your cache as files, over database, to redis, memcached, and others.
I won't go into too much details on how this works under the hood - if you're curious, the official caching documentation is always a great starting point.
Single Purpose Caching
What's important is that Laravel offers a global way of caching data, which it also uses for several specific purposes.
Laravel has a large number of config files, with even more values moved to the environment file. Instead of looking through all of those whenever a config value is needed, they are all saved in one location.
If your app has a lot of routes, finding the one matching the current request can be slow. Optimizing them and caching your optimized route files speeds this process up.
Instead of compiling your blade views for each request, the view cache allows you to precompile them and serve already finished views when they are needed.
The last cache stores all of your events and events listeners in a single file so event handling requires less resources.
Caching Custom Data
On top of that you can also use Laravel's caching system for your own application logic. Any data you retrieve from the database or an API, and anything that you process or calculate, can easily be stored and retrieved from the cache.
There are different ways to handle this, and the caching documentation covers them in detail. Here's one simple example:
In this case the array of posts is stored in the cache for 60 seconds under the key of posts. When this code snippet is executed, it first checks the cache to see if there is a value for that key that's less than 60 seconds old.
If such a value is found, the cached information is assigned to
$posts without touching the database. Otherwise Eloquent is used to get all posts from the database (via
Posts::all()), which are then both assigned to the variable and also stored in the cache again.
With these simple yet powerful functions you can drastically increase the performance of your custom Laravel application.
Statamic's Caching Levels
While Laravel allows you to manually cache your content wherever you want, Statamic as a CMS does a lot of this out of the box. It for example uses the Application Cache to store the differently sized and cropped images you're using on your site so they don't have to be recreated on each request.
On top of that it adds two more layers of caching that are particularly interesting: the stache and static caching.
There is a reason most CMS are using a database instead of storing their content in files. Constantly writing and reading a large amount of files on disk can be very slow, definitely too slow for today's impatient web users.
To solve this issue without the need for MySQL or alike, Statamic uses a caching layer called the stache. So instead of writing and reading files directly, you mainly interact with the stache, which contains an optimized version of your data and is stored in the application cache.
This caching layer contains indexes of all you site's content which contain only the most important information (e.g. an id, path, or slug) and can quickly be searched, for example when trying to output all collection items that match a specified criteria.
Whenever you are filtering by a specific value, another index is created to run that query efficiently in the future.
So in a way the stache is Statamic's way of giving you database level performance without the need for an actual database.
I've talked about this feature already other posts, since the speed boost if gives you is simply amazing. The last layer of caching doesn't just store single indexes, but the entire HTML output that is generated for a specific request.
This does come with some drawbacks regarding functionality, but lets Statamic run all queries and calculations only ones and then return only the final result to every subsequent request.
The HTML that will be returned can be stored inside the application cache (which is referred to as half-measure static caching) or as HTML files to be delivered by the web server without even booting Statamic (full-measure).
This last layer is what user's will mostly come in touch with, as it both offers the biggest speed-up, as well as the most potential issues like serving outdated versions of your content.
Clearing Your Cache
Caching is great since it solves a lot of issues and improves performance dramatically. But every now and then it can also get in the way.
Especially when changing configuration setting or the underlying infrastructure, you might run into hard to debug issues caused by outdated cache values.
When using the static caching you can also run into cases where you update the title of a blog post but your cached front page still displays the old information.
In situations like these it's important to know how to dump the cache and start with new, up-to-date information.
Clearing the Application Cache
As described above, almost all caching uses the Laravel application cache to store data. So in most cases a single command line call is enough:
php artisan cache:clear
This will empty the application cache, removing cached routes, views, events, config values, and even Statamic's stache indexes and (only half-measure) static cache.
Clearing (or Seeding) Specific Caches
While that is convenient, in some cases you might have the need to only clear a specific cache but leave everything else the way it is. Laravel and Statamic also provide commands for those scenarios - allowing you to empty (clear) or fill (cache or warm) any cache you want.
Laravel's Config Cache
php artisan config:cache
php artisan config:clear
Laravel's Route Cache
php artisan route:cache
php artisan route:clear
Laravel's View Cache
php artisan view:cache
php artisan view:clear
Laravel's Event Cache
php artisan event:cache
php artisan event:clear
php please stache:clear
php please stache:warm
php please stache:refresh
Statamic's Static Caching
php please static:clear
php please static:warm