How caching works
Goal: understand the two caches every Cloud Platform application sits behind, Varnish in front and memcached behind, well enough to predict what gets cached, control cache lifetime from Drupal, and enable memcached correctly.
Everything below is current-generation (Cloud Next) behavior. Cloud Classic differs in a few details, each one linked to docs.acquia.com where it comes up.
What you’ll have when you’re done
Section titled “What you’ll have when you’re done”- A mental model of the request path and which layer answers which requests.
- The cacheability rules: why a given response is or isn’t stored by Varnish, and for how long.
- Drupal configured to feed Varnish a sensible cache lifetime, and memcached enabled if your site benefits from it.
Prerequisites
Section titled “Prerequisites”- A Cloud Platform application (see ship code to environments if you’re new to the platform)
Jump to a task:
- Know the request path
- Learn what Varnish will and won’t cache
- Set the Varnish TTL from Drupal
- Vary the cache on cookies, if you must
- Enable memcached if your site benefits
-
Know the request path
Section titled “Know the request path”A request that Varnish can answer never reaches PHP at all. A request that gets through runs your Drupal code, which in turn consults its own caches; with memcached enabled, most of those internal cache reads come from memory rather than the database. The two layers solve different problems: Varnish protects the whole stack from anonymous traffic, memcached makes the requests that do get through cheaper.
-
Learn what Varnish will and won’t cache
Section titled “Learn what Varnish will and won’t cache”Varnish caches two kinds of responses:
- Anonymous page responses. Full HTML responses to visitors without a session.
- Static assets (images, JavaScript, CSS) for anonymous and authenticated visitors, as long as the assets aren’t in Drupal’s private file system. Files larger than 10 MB are never cached.
Whether a specific response is stored comes down to a few rules:
- Only
GETandHEADrequests are cacheable. Any code answeringHEADrequests can set aCache-Controlresponse header and Varnish respects it. - Session cookies bypass the cache entirely. A request whose
Cookieheader matchesS?SESS[a-zA-Z0-9]*,NO_CACHE, orPERSISTENT_LOGIN_*is passed straight to Drupal, and its response is not stored. This is why a logged-in editor always sees fresh content. Requests carrying anAuthorization: Basicheader bypass the cache the same way. - Static assets have cookies stripped. Cookie headers, session ones included, are removed from asset requests so the assets stay cacheable even for logged-in users.
- Status codes: responses of
302and above are not cached, with one exception:404. Both404and301responses are cached for a minimum of 15 minutes regardless of what your application asks for, to blunt cache stampedes. A response header can opt a page out of that floor, but Acquia recommends against it; see Varnish headers on docs.acquia.com. - Lifetime comes from your headers. How long a stored response lives is set by
Cache-Control: max-age(ors-maxage, which wins when both are present). A missing, invalid, or negativemax-agemeans the response isn’t cached.
Varnish configuration itself is Acquia-managed and shared; you steer it entirely through response headers. Custom Varnish configuration exists only for Cloud Platform Enterprise subscriptions with dedicated load balancers; to request it, ask your Acquia account manager, or contact Acquia Support. Do not install the Varnish Drupal module: it expects direct load-balancer connections the platform doesn’t provide.
-
Set the Varnish TTL from Drupal
Section titled “Set the Varnish TTL from Drupal”The single Drupal setting that drives Varnish is Browser and proxy cache maximum age on the Performance page (
/admin/config/development/performance). It becomes themax-agein your responses’Cache-Controlheader, which is the lifetime Varnish uses. Set to no caching, Drupal sendsmax-age=0and nothing is stored; a reasonable production value is 6 to 12 hours. Long lifetimes are what make Varnish effective, and the purge tooling is what makes long lifetimes safe when content changes. -
Vary the cache on cookies, if you must
Section titled “Vary the cache on cookies, if you must”The platform’s Varnish ignores almost all cookies for cache-variation purposes. If your application serves different cacheable content based on a cookie, only these are usable:
- Three generic cookies,
acquia_a,acquia_b, andacquia_c, arrive at your application asX-Acquia-Cookie-A/B/Crequest headers. - One custom cookie prefixed
acquia_extract:(for exampleCookie: acquia_extract:CART_ID=1234;) arrives asX-Acquia-Cookie-Key: CART_IDplusX-Acquia-Cookie-Value: 1234.
Respond with a
Varyheader naming the relevantX-Acquia-Cookie-*headers to store one cache object per value, orCache-Control: no-cacheto keep those responses out of the cache. Keep variations per response to roughly ten or fewer: varying on unpredictable values (user IDs, timestamps) fills the cache and defeats it. Details and worked examples are in Cookies and Varnish on docs.acquia.com. - Three generic cookies,
-
Enable memcached if your site benefits
Section titled “Enable memcached if your site benefits”With memcached enabled, most of Drupal’s cache bins live in memory rather than in the database’s
cache_*tables, cutting database load on requests that reach PHP. Memcached is a cache in front of the database, not a replacement for it. The bookkeeping that tracks cache tag invalidations stays in the database, and so does any bin pinned there in settings. Everything memcached holds is a copy Drupal rebuilds if it is evicted. It helps most on large applications with heavy database activity; a small or already-fast site can actually get slower, so compare performance with it on and off before committing.On Cloud Next environments memcached is available by default with 64 MB allocated, adjustable per environment with
acli api:environments:update myapp.prod --memcached_limit='128' --task-wait. Acquia recommends a mid-range 128 MB or 256 MB when the default runs short, and advises against exceeding 2048 MB, an allocation only the largest multisite deployments benefit from (and one that can incur fees on subscriptions with Cloud Capacity Unit limits). Allocation for both platform generations is detailed in Configuring PHP settings on docs.acquia.com.To enable it for a site running the current Drupal version:
-
Add the Memcache API and Integration module to your codebase:
Terminal window composer require drupal/memcache -
On Cloud Next, that’s the whole wiring: the platform’s included configuration both selects memcache as Drupal’s cache backend and injects the connection settings (
memcache_servers,memcache_key_prefix), so there is nothing to add tosettings.php. Do not set those values yourself. Details are in Enabling Memcached on docs.acquia.com. -
Rebuild caches:
Terminal window drush cr --uri=example.comthen truncate the tables whose names start with
cache_once. This clears out rows written before the switch, which the moved bins will never read again; it reclaims space, nothing more. Truncate rather than drop, and leavecachetagsand every other table alone: bins still on the database keep using their tables, and Drupal repopulates a truncated cache table on demand.
-
When something goes wrong
Section titled “When something goes wrong”A deployed change isn’t showing
work through fix stale content step by step.
Varnish suddenly stops caching anything
almost always a module setting a session-like cookie for anonymous visitors; see the cookie pitfalls.
Memcached seems too small
the Memcache Admin submodule’s report (Reports > Memcache statistics) shows evictions; a high eviction rate relative to activity means the cache is thrashing and needs a bigger allocation.
Next steps
Section titled “Next steps”- Fix stale content: diagnosis and purging when the cache holds the wrong thing.
- Ship code to environments: where cache purging fits into a deploy (Cloud Hooks).
- What the platform logs: watching cache behavior in production.
Was this page helpful?
What went wrong?
Still stuck? Contact Acquia Support (opens in a new tab)