Skip to content

Goal: a change is deployed but visitors still see the old content. Find which cache layer is serving the stale response and purge it, without flushing more than you have to.

If you haven’t read how caching works on Cloud Platform, the short version: Varnish serves anonymous responses from memory in front of the stack, and Drupal keeps its own caches behind it. Either layer can be the one holding your old content.

  • The stale response traced to a specific layer (Varnish, Drupal, or the browser).
  • That layer purged, as narrowly as the situation allows.
  1. Test logged out, or from a terminal. A logged-in session carries a session cookie, and requests with session cookies bypass Varnish entirely; this is the classic trap where the editor sees the new content (“works for me”) while every anonymous visitor gets the cached old page.

    Terminal window
    curl -sSLIXGET https://www.example.com/pricing
  2. The response tells you which layer answered:

    Header What it tells you
    X-Cache: HIT Varnish served it from memory; PHP never ran. Stale content here means Varnish is holding an old copy.
    X-Cache: MISS The request went through to Drupal. Stale content here is Drupal’s own caches, not Varnish.
    Age Seconds the served object has been in the Varnish cache. 0 means it wasn’t served from cache.
    Cache-Control The lifetime your application asked for. max-age=0 or no-cache, must-revalidate means Drupal is telling Varnish not to cache at all (check the Performance page setting, see the guide).
    X-Drupal-Cache HIT/MISS for Drupal’s internal page cache, behind Varnish.
    X-AH-Environment Which environment answered, by environment name (dev, test for the environment labeled Stage, prod). If this isn’t the environment you deployed to, you’re debugging the wrong target (or DNS).
    Vary Which request headers split the cache into variants. Missing Vary on cookie-dependent content is a common cause of the wrong variant being served.

    Decision rule:

    • X-Cache: HIT with a large Age → Varnish holds an old copy. Go to step 3.
    • X-Cache: MISS and still stale → the staleness is inside Drupal (render cache, page cache, or the change genuinely didn’t deploy). Go to step 4.
    • Fresh in curl, stale in the browser → it’s the browser cache (or a CDN in front of Acquia, if you run one). Hard-reload; check any CDN separately.
  3. Three ways, from most to least targeted:

    Ongoing invalidation: Acquia Purge. The Acquia Purge module (with the Purge module framework) is the platform-recommended way to keep Varnish in sync from inside Drupal: when content changes, the affected URLs and cache tags are purged automatically. If you’re firefighting stale content regularly, installing it is the fix; the one-off methods below are for right now.

    One page, right now: drush. The Purge framework can invalidate a single path or tag from the command line. Add the direct-invalidation processor once, then invalidate:

    Terminal window
    drush p:processor-add drush_purge_invalidate
    drush p:invalidate url https://www.example.com/pricing

    Tag-based invalidation clears everything rendered from a piece of content, whichever URLs it appears on:

    Terminal window
    drush p:invalidate tag node:42

    Two caveats from the platform’s own guidance:

    • Varnish caches per domain, so a page reachable via both www.example.com and cms.example.com needs one invalidation per domain.
    • Purging Varnish does nothing if Drupal’s own cache still holds the old render. Clear the relevant Drupal cache entry first (that’s what tag invalidation does for you).

    Whole domain: acli. For a full flush of one or more domains, acli api:environments:domain-clear-caches <env> example.com clears one domain, and acli api:environments:clear-caches <env> domain1.example.com domain2.example.com clears several at once. Both take an environment ID or alias and queue a task; add --task-wait to block until it finishes. Because each is a single command, a Cloud Hook or CI job can purge as part of a deploy. The Cloud UI has the same flush on the environment’s page; see Purging Varnish cache on Cloud Platform on docs.acquia.com.

  4. If Varnish shows MISS and the content is still old:

    1. Confirm the deploy actually landed: acli app:vcs:info myapp --deployed prints the branch or tag each environment has deployed, or read git log over SSH.

    2. Rebuild Drupal’s caches on the environment:

      Terminal window
      acli remote:drush myapp.prod -- cr
    3. Re-test with curl. If the page is fresh on MISS but old visitors still get a HIT on the previous copy, finish with a targeted Varnish purge from step 3; a Drupal cache rebuild does not touch Varnish.

Recurring staleness is usually a cacheability bug, not a purge problem:

A module sets a session-like cookie for everyone

Any cookie matching S?SESS*, NO_CACHE, or PERSISTENT_LOGIN_* stops Varnish caching for that visitor. One misbehaving module can quietly disable Varnish site-wide; the symptom is X-Cache: MISS on every request and a suddenly busy web tier.

Content depends on a cookie Varnish doesn’t vary on

The platform only varies the cache on acquia_a/acquia_b/acquia_c and one acquia_extract: cookie, and only when your response sends the matching Vary header. Anything else gets one shared cache object for all visitors: the first response wins and everyone else sees it. See varying the cache on cookies.

404/301 responses look stuck

The platform caches those for at least 15 minutes no matter what your application says. A page that was briefly a 404 keeps 404ing after you fix it; wait out the floor or purge the URL.

Was this page helpful?