Cache max-age
Cache max-age = time-based dependencies
Cache max-age is similar to the HTTP max-age directive in the Cache-Control header.
Why?
Cache max-age provides a declarative way to create time-based cache dependencies.
Some data is only valid for a limited amount of time. In such cases, you want to specify an appropriate max-age. However, in Drupal 8 core, we typically don’t have data that is only valid for a limited time; instead, we usually cache permanently (see below) and rely entirely on cache tags for invalidation.
What?
Cache max-age is a positive integer representing the number of seconds.
It is passed as a single integer, since a cache item logically can only have one max-age.
Examples:
- 60 means cache for 60 seconds
- 100 means cache for 100 seconds
- 0 means cache for 0 seconds, i.e., do not cache
- \Drupal\Core\Cache\Cache::PERMANENT means cache forever — it will only ever be invalidated by cache tags (in other words: ∞ or infinite seconds)
So, for example, if you want to prevent a rendered block from being cached, you should set its max-age to 0.
Example for most render arrays:
$build['#cache']['max-age'] = 0;
Example in a function:
\Drupal::cache()->set('my_cache_item', $school_list, REQUEST_TIME + (86400));
If you want to change the max-age of a block to 0, you should implement the getCacheMaxAge method.
Max-age Limitations
Unfortunately, max-age does not work for anonymous users and the core Page Cache module. For example, see the following issues:
- #2352009: [pp-3] Forward max-age of elements into page and page cache headers
- #2449749: Add #cache['downstream-ttl'] to force expiry after a given time + fix #cache['max-age'] logic by adding #cache['age']
- #2835068: PageCache caches uncacheable responses (violating HTTP/1.0 specs) + D8 intentionally disables HTTP/1.0 proxies = WTF
- #2951814: Always set X-Drupal-Cache and X-Drupal-Dynamic-Cache headers even for uncacheable responses
Until these (and possibly other) issues are resolved, keep in mind that setting a max-age on a render array included in a page is not enough for anonymous users to see a new version after the max-age expires. Meanwhile, the contributed module Cache Control Override tries to mitigate the issues. You may also have luck setting a custom cache tag on time-sensitive content pages and manually invalidating those tags with hook_cron(). Good luck!
Drupal’s online documentation is © 2000-2020 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution-ShareAlike 2.0. PHP code is distributed under the GNU General Public License.