Loading...


Related Products


Date Published: February 5, 2025

How does Drupal page cache work?

Drupal page caching keeps copies of the fully rendered HTML for a page; this can include content, views, images, and so on. When you troubleshoot issues with caching, understanding how Drupal handles the page cache can help you narrow down the problem more quickly.

A deep dive into the bootstrap and page caching process is covered in Digging Deeper into Drupal Page Caching.

What's stored, and how?

Drupal's page cache stores the fully rendered HTML of each page that is required to cache. It does this using a Cache ID (cid) that corresponds to the actual URL used to request the page. This is similar to how Varnish identifies what to cache.

As the URL is the cid, URIs that map to the same logic are cached as different items in the Drupal page cache. For example, if your front page is actually mapped to /node, these are content-equivalent but are cached as separate items. For example, these URIs are functionally equivalent, but are stored separately:

The following code snippet returns a portion of the cached data from the page cache, regardless of the database storage mechanism:

drush ev '$uri = "http://example.com/"; $x = cache_get($uri, "cache_page"); if ($x) { $body = gzinflate(substr(substr($x->data['body'], 10), 0, -8)); $x->data["body"] = substr($body, 0, 512) . " [... snip!]\n"; foreach (array("created", "expire") as $element) { if ($x->$element) { $x->$element .= " [" . strftime("%c", $x->$element) . "] == " . ($x->$element - time()) . " secs from now"; } }  print_r($x); } else { echo "No data found!\n"; }'

This alternative snippet displays the metadata about a cached page, or tells you that there was no matching cache entry, but does not display the actual content:

drush ev '$uri = "http://example.com/page"; $cached_page = cache_get($uri, "cache_page"); $cached_page->data['body'] = "BODY"; if (is_numeric($cached_page->created)) { $cached_page->created_h = date('r', $cached_page->created); $cached_page->expire_h = date('r', $cached_page->expire); } else { $cached_page = "no cache entry\n"; } print_r($cached_page);';

Here's an example of what you might get in return:

stdClass Object(    [cid] => http://example.com/page    [data] => Array        (            [path] => page            [body] => BODY            [title] => Page not found            [headers] => Array                (                    [Content-Type] => text/html; charset=utf-8                    [Content-Language] => en                    [Status] => 404 Not Found                    [X-UA-Compatible] => IE=edge,chrome=1                    [X-Generator] => Drupal 7 (http://drupal.org)                )             [page_compressed] => 1        )     [created] => 1402494021    [expire] => -1    [serialized] => 1    [created_h] => Wed, 11 Jun 2014 07:40:21 -0600    [expire_h] => Wed, 31 Dec 1969 16:59:59 -0700)

If the output page has messages (output by drupal_set_message()), this page is not stored in page cache during this request.

The X-Drupal-Cache header can also be added to responses, and you may see these in the Array:

  • X-Drupal-Cache: MISS for pages not served from cache display.
  • X-Drupal-Cache: HIT for pages served from cache.

For more details on these messages, visit function _drupal_bootstrap_page_cache .

Clearing items from the Drupal page cache

Similar to any other cache clearing mechanism, clearing items from the Drupal page cache is dependent on several variables.

  • Each item in the page cache might have different expiry times, after which, it is purged from the Drupal page cache or ignored.
  • Some operations purge every stale (or expired) item from the page cache.
  • The expire property on the cache object tells you when a particular item expires.
  • The Drupal page cache normally tags each Page cache item with the CACHE_TEMPORARY constant (internally, -1) to know when the item expires.

Core database caching versus Memcache

Differences between page cache in Drupal core cache and memcache.inc

 Drupal core cachingMemcache
How items are tagged for expirationItems are tagged with expire = CACHE_TEMPORARY (-1)Instead of tagging items with CACHE_TEMPORARY, it sets expiry to a specific time, one month in the future.
Actions and API calls that clear out items from the page cache
  • Calling cache_clear_all(NULL, "cache_page");
  • Running drush cc all
  • Calling system_cron() (which is included in the normal cron.php or drush cron runs).
  • Editing or creating any single node through the user interface
  • Editing a View.
  • Enabling or disabling a module.
  • Calling cache_clear_all(NULL, "cache_page");
  • Running drush cc all

For more information, visit Temporary cache is not being flushed on cron run causing issues with cache_form stored in database.

How does Minimum cache lifetime work?

The minimum cache lifetime is equivalent to setting the cache_lifetime Drupal variable. It prevents Drupal from clearing page and block caches after changes are made to nodes or blocks, for a set period of time. This can cause unexpected behavior when editing content or when an external cache such as Varnish is employed. Minimum cache lifetime should be used with caution. If you are unsure, set minimum cache lifetime set to 0.

If you are self-hosted, you can run into a situation where not all caching clears upon node_update. This can be because of the differences with memcache, noted previously. In this particular example, a customer was instructed to create a custom module to force a cache_clear_all on the home page after a node_update, which wipes out the page cache in memcache:

Did not find what you were looking for?

If this content did not answer your questions, try searching or contacting our support team for further assistance.

Back to Section navigation
Back to Site navigation