Skip to content

Powered by Grav

The front cache & Drupal's page cache

The front cache & Drupal's page cache

Two layers serve whole pages before Drupal does any real work: the Nginx front cache (BOA calls it Speed Booster) and Drupal's own page cache, which on BOA lives in the fast Redis/Valkey object cache. They're tuned to work together, and the defaults are right for almost every site — but both have a dial, and there's a right and a wrong way to make a page dynamic.

Speed Booster: the Nginx micro-cache

Speed Booster runs in micro-caching mode: a page may be served straight from Nginx for a short window — 10 seconds by default — without PHP or Drupal running at all. Ten seconds sounds tiny, but on a busy page it means one page build serves everyone who arrives in that window, which flattens traffic spikes beautifully while keeping content essentially fresh.

It's smarter than a blunt page cache, and worth knowing exactly how:

  • Logged-in users are cached too — each in their own bin. The cache key includes the visitor's session, so logged-in visitors get a private micro-cache (same short window) that can never leak between users, and a separate device class (desktop, tablet, smartphone) keeps mobile themes safe to serve.
  • It steps aside when it must. Any form submission (POST) switches the cache off for that visitor for 15 seconds, and requests to /user*, /admin*, cart and checkout paths always bypass it — so editing, logging in and shopping never see a stale page.
  • Crawlers get much longer. Known robots and search-engine spiders are forced to accept a much longer cache window than human visitors, so bot swarms never stampede your site.
  • You can raise the anonymous window. speed_booster_anon_cache_ttl sets the anonymous-visitor TTL in seconds. Values of 10 or below are ignored — 10 is the floor.
  • On a .dev. preview URL the window drops to 1 second, so development work is effectively uncached at this layer too.
INI
; sites/<your-domain>/modules/boa_site_control.ini
speed_booster_anon_cache_ttl = 30

If you raise the TTL meaningfully, consider enabling the Purge and Expire modules on your site: they selectively purge affected front-cache entries when a node or comment changes, so a longer TTL doesn't mean serving stale content until it expires. And if you're on Drupal 6 or 7, read the AdvAgg section below — a raised TTL is exactly what turns a routine cache clear into temporarily broken styling.

Drupal's page cache stays on — here's why

BOA keeps Drupal's own full-page cache enabled, and stores it in Redis/Valkey. The two layers cover for each other: the front cache absorbs the repeat traffic within its few-second window, and the page cache makes the request that misses the front cache (the first one after each window expires) nearly free as well, because the page comes ready-made from memory.

That's why disable_drupal_page_cache = TRUE is almost always the wrong move. With the front cache holding pages for only seconds, turning the page cache off means Drupal rebuilds pages from scratch all day — your site gets noticeably, randomly slower for every anonymous visitor, even if you raise the front-cache TTL. (Legacy note: if the Boost module complains that the page cache is on, let it complain — BOA's default is deliberate.)

Setting What it does Default
speed_booster_anon_cache_ttl Seconds an anonymous visitor's page may be served from the Nginx front cache. Values of 10 or below are ignored. 10
disable_drupal_page_cache TRUE switches off Drupal's own full-page cache. Read the section above before even thinking about it. FALSE

Both work in either control file — see Platform and site INI settings for the mechanics.

When a cache clear breaks your styling: AdvAgg

This one shows up almost exclusively on Drupal 6/7 sites that raised the front-cache TTL: someone clears the site's caches, and for a while visitors get pages with broken or missing CSS and JavaScript — then it heals on its own.

The mechanism: Drupal 6/7's standard aggregation deletes its old aggregate CSS/JS files when caches are cleared, but pages already sitting in the front cache still reference those now-deleted files, so every visitor served from the cache for the rest of the window gets a page whose stylesheet links go nowhere. With the default 10-second window nobody ever notices. With a raised TTL, the breakage lasts as long as your window has left to run.

The remedy is the AdvAgg (Advanced CSS/JS Aggregation) module, bundled with every BOA-built Drupal 6 and 7 platform — it lives in the platform's shared o_contrib/o_contrib_seven module directories, and a copy you upload to sites/all/modules/advagg is respected as an override (see Modules BOA manages for how the bundled extras work). AdvAgg is built around exactly this problem: it generates aggregates with stable names and leaves the existing aggregate files in place on a flush instead of purging them, so pages cached before the clear keep rendering correctly after it.

Enabling the module is all you do — BOA notices. The nightly maintenance pass detects AdvAgg enabled on your site and sets advagg_auto_configuration = TRUE in your site's control file, which applies a tuned, core-version-specific AdvAgg profile (bundler, compression, gzip, async generation) at the settings level. If you later disable the module, the same pass flips the setting back to FALSE — it always mirrors the module's actual status, so there is nothing to maintain. (On .dev. preview URLs the tuned profile is not applied, in line with the rest of the no-cache dev view. And on Drupal 8 and newer none of this machinery applies — BOA doesn't bundle or auto-configure AdvAgg there; if you want it, you add and configure it yourself like any contrib module.)

Making one URL truly dynamic (the right way)

First, two cases this section is not for: a one-off uncached look at a page (append ?nocache=1 to the URL instead — that single request skips both page-level caches), and development (use the .dev. preview URL).

Sometimes one page genuinely must be rebuilt for every anonymous visitor — a per-visitor result with no cookie or form involved. Don't disable caching site-wide for that. Add a targeted exception to your site's local.settings.php instead. On Drupal 6/7:

PHP
if (preg_match("/^\/(?:live-results|stock-ticker)/", $_SERVER['REQUEST_URI'])) {
  header('X-Accel-Expires: 1'); // skip the Nginx front cache for this URL
  $conf['cache'] = 0;           // skip Drupal's page cache on the fly
}

The first line exempts the URL from Speed Booster; the second keeps Drupal from serving it out of the page cache. On Drupal 8+ the front-cache line is the same, and the page-cache line becomes the config override $config['system.performance']['cache.page.max_age'] = 0;. Everything else on the site stays fully cached.

© 2026 BOA Documentation. All rights reserved.