Cache

Drupal's cache keeps results that are slow to compute, such as rendered HTML and whole pages, and invalidates them through cache tags when data changes.

Learn DrupalDrupal glossary

Cache in Drupal is stored data that saves the site from computing the same thing again: rendered HTML, plugin and YAML discovery results, and whole pages. Each cached item carries cacheability metadata: cache tags (what data it depends on), cache contexts (what it varies by) and a maximum age (how long it stays valid).

How caching works in Drupal 11

The Cache API stores any data under a cache ID. Code asks for the item, and if nothing is returned it computes the value and saves it. Items live in cache bins that can be configured separately. Core bins include default, bootstrap, render for HTML such as pages and blocks, data, discovery and memory. By default the bins are stored in the database, except in-memory bins such as memory, and settings.php can send a bin to another backend, such as APCu or Memcache.

Cacheability metadata

  • Cache tags describe dependencies on data. Examples are node:5 for one node, node_list for any node listing and config:node_type_list for the list of content types. Invalidating a tag marks every item that carries it as stale, across all bins. Entities get their tags and invalidate them on save and delete without extra code.
  • Cache contexts make variations of the same item, like HTTP's Vary header. Examples are user.permissions, languages, url.path and route.
  • Max-age is a lifetime in seconds. A value of 0 means the item is not cacheable. The permanent value, -1 (the constant Cache::PERMANENT), means it lasts until a tag invalidates it. Core mostly caches permanently and relies on tags.

These values are set in the #cache property of a render array and bubble up to the parent render arrays, so the page as a whole inherits what its parts need.

Page caches

Two core modules cache at page level. The Internal Page Cache stores pages for anonymous visitors. It is enabled by default and builds its cache ID from the scheme, host, path, query string and format. It does not use the browser and proxy maximum age from the Performance page. The Dynamic Page Cache caches pages minus the personalized parts, which it turns into placeholders, so it helps anonymous and logged-in users. It reads the cache contexts of each part to decide what it can store. The x-drupal-cache response header reports HIT or MISS for the Internal Page Cache.

Clearing caches

Drush has two commands. drush cache:rebuild (cr) rebuilds all caches. drush cache:clear (cc) clears a named cache or bin. In the user interface, use the Clear all caches button on the Performance page.

What every cached item in Drupal carries, and how it is invalidatedA cached item carries three kinds of metadata: cache tags say what data it depends on, cache contexts say what it varies by, and max-age says how long it stays valid. They are set in the #cache property of a render array and bubble up to the page. Invalidating a tag marks every item that carries it as stale, in all bins.Cacheability metadata, set in #cache of a render arrayCache tagsWhat data it depends onnode:5 node_listconfig:node_type_listCache contextsWhat it varies byuser.permissionslanguages url.pathMax-ageHow long it is valid0 = not cacheable-1 = until invalidatedbubbles up to the parent render arrays and the pageThe pageInherits what its parts needCache::invalidateTags(['node:5'])Every item with that tag is stale,in all cache binsmakes staleInternal Page Cache stores pages with their tags; Dynamic Page Cache also varies by contexts.
What a cached item carries and how invalidating a tag makes it stale.

Example

A render array that shows teaser text for one node, varying by interface language:

use Drupal\Core\Cache\Cache;

        $build['teaser'] = [
          '#markup' => $text,
          '#cache' => [
            'tags' => ['node:5'],
            'contexts' => ['languages:language_interface'],
            'max-age' => Cache::PERMANENT,
          ],
        ];

        // Later, after changing the underlying data:
        Cache::invalidateTags(['node:5']);

On the command line, drush cr rebuilds everything after a deploy or after adding a new Twig template.

Common mistakes

  • Personalized output without a context. If a render array shows something that differs per user, it has to vary by the user context. Otherwise one visitor's version can be served to another.
  • Leaving the Internal Page Cache on for personalized anonymous pages. It assumes anonymous pages are identical. A shopping cart for anonymous visitors, for example, needs it off or the personalization done with JavaScript.
  • Expecting the maximum age setting to control it. The browser and proxy maximum age on the Performance page does not govern the Internal Page Cache.
  • Setting max-age to 0 on a small part. Metadata bubbles up, so one uncacheable element can limit how much of the page Drupal can cache.
  • Using a development setup in production. Null cache backends and Twig debugging belong on a local copy only. Test with caches on as well.

For marketing and content teams

You rarely need to clear caches to see an edit: saving content invalidates the cache tags of that content. When a change does not show, check three things in order: open the page in a private window to rule out the browser, ask whether a CDN or proxy sits in front of the site, and then ask a developer to check the cache tags on the affected page element. A developer can invalidate a single tag instead of rebuilding everything, which is the more targeted fix.

Sources

Questions about the Drupal cache

The Internal Page Cache stores whole pages for anonymous visitors and assumes those pages are the same for everyone. The Dynamic Page Cache stores pages minus their personalized parts, so it also helps logged-in users. Both are core modules, and the Standard and Minimal install profiles enable both.

Run drush cache:rebuild (short form drush cr), or use the Clear all caches button on the Performance page at /admin/config/development/performance. To clear one bin only, drush cache:clear bin lets you pick it.

Cache tags are labels that say which data a cached item depends on, such as node:5 for node 5 or node_list for any node listing. When that data changes, Drupal invalidates every item carrying the tag, in every cache bin.

Saving content invalidates the cache tags of that content automatically, so most edits show at once. If an old version stays, look for a cache Drupal does not control, such as the browser, a CDN or a reverse proxy, or for a custom element that is missing cache tags.

You can turn off the render and Dynamic Page Cache bins on a local machine, and core's example.settings.local.php shows how. Never do this on production, and test with caching on too, because missing cache metadata only shows up when caching works.

Related terms

All Drupal terms from A to Z