Drupal has an intricate caching system, referred to as the Cache API, to improve its performance. The caching system stores data and previously generated output, and tries to reuse it whenever possible.
Only when there is no appropriate cached data available will Drupal rebuild the output. Rebuilding output takes time and processing resources, so Drupal will try to find and use cached content whenever it can.
Anything can be stored in the cache:
- Raw data fetched from an outside system.
- Content fetched from Drupal's own database tables.
- Bits of generated html, ready for output …
Let's look at a few important terms and concepts.
We will limit ourselves to the basics, as the Cache API is a large and complex subsystem. If you want to dig deeper, have a look at the Cache API reference documentation.
Cache Bin
Cache storage is separated into bins, each containing various cache items. Each bin can be configured separately.
In this course we will not deal with configuring cache bins; we use the default cache bins with their default settings.
Cache Item
Each distinct chunk of data (raw data, generated html, …) that's stored in a cache bin is referred to as a cache item
Cache ID
Each cache item Cache ID (cid): a unique text string that uniquely identifies the cache item.
Cache Lifetime
When you store a cache item you must indicate how long it remains valid.If you don't specify a lifetime value, the default Cache::PERMANENT will be assumed, and the block will be cached until you clear the caches.
Stale Cache Items
Cache items are called stale (not fresh) when they are older than their specified cache lifetime, or when you have decided they are out of date and need to be replaced with fresh data.
Deleting Cache Items
There are two ways to remove an item from the cache:
- Deletion: removing the item permanently from the cache.
- Invalidation: a "soft" delete that only marks items as "invalid", meaning "not fresh" or "not fresh enough".
Invalid items are not usually returned from the cache, so in most ways they behave as if they have been deleted. However, it is possible to retrieve invalid items, if they have not yet been permanently removed by the garbage collector.
You can manually remove specific cache items whenever you want, or you can wait for the cache(s) to be cleared by the general "clear caches" mechanism that is invoked by a user or by the system update process.
Cache Tags
When you store a cache item, you can specify one or more cache tags.
By convention, cache tags take the format [prefix]:[suffix], and are used to group cache items together. Grouping is necessary to correctly invalidate several related cache entries if one of them becomes stale.
From the Cache API reference documentation:
Cache tags are a solution to the cache invalidation problem:
For caching to be effective, each cache item must only be invalidated when absolutely necessary. (i.e. maximizing the cache hit ratio.)
For caching to be correct, each cache item that depends on a certain thing must be invalidated whenever that certain thing is modified.
A typical scenario:
A user has modified a node that appears in two views, three blocks and on twelve pages. Without cache tags, we couldn't possibly know which cache items to invalidate, so we'd have to invalidate everything. We'd had to sacrifice effectiveness to achieve correctness. With cache tags, we can have both.Example
The following example adds two cache tags to a render array that contains the data that will be delivered for output:
→ In a next unit you will see and recreate practical examples that show where and how to use this.
To learn more about cache tags, refer to the Cache Tags documentation.
Cache Contexts
Some computed data depends on contextual data, such as the user roles of the logged-in user who is viewing a page, the language the page is being rendered in, or the currently active theme.
Often-used cache contexts include:
- User (cache per user)
- Role (cache per role)
- Route (cache per route)
For a full list of cache contexts, refer to the Cache contexts documentation.
Typically, the cache context is specified as part of the #cache property of a render array.
The following example adds the 'user' cache content to the list of cache contexts, as part of the render array that contains the data that will be delivered for output:
$build['#cache']['contexts'][] = 'user';→ In a next unit you will see and recreate practical examples that show where and how to use this.
Summary
- Caching is a notoriously complex problem in Computer Science. Drupal does its best to solve this problem with the Cache API.
- Blocks use the Cache API to improve performance.
- Cache items need a unique cache id (cid).
- Unless you specify a cache lifetime for items, they will be invalidated the next time the cache is cleared.
- Cache tags let you group related cache items so they can all be invalidated together when necessary.
- Cache contexts let you specify cached variations of content for different situations - or different contexts.