Drupal with Varnish and the Purge module

Varnish can serve most anonymous Drupal pages from memory, but only if invalidation is designed in from the start. This page explains how the Purge module and a Varnish purger keep cached pages current by cache tag.

On this page

When Drupal with Varnish and Purge is worth the build

Put Varnish in front of Drupal when anonymous pages are expensive to generate, traffic arrives in spikes, and editors still expect a published change to appear on the site quickly. Varnish is an HTTP reverse proxy: it stores complete responses from Drupal and serves repeat requests from memory, so Drupal only builds a page when the stored copy is missing or has been invalidated. The decision is less about whether Varnish is fast and more about whether your traffic is mostly anonymous, cacheable pages. Before you commit, measure the share of requests that reach PHP and the database, the cache hit ratio at your current edge, and how often editors publish changes that must appear within a stated time. If most traffic is logged in or personalized, the proxy will carry less of the load and the build may not pay back its effort.

Purge is the Drupal side of that loop. The Purge module collects invalidation requests when content changes, places them in a queue, and dispatches them to one or more purgers, such as the Varnish purger, which tells Varnish to drop the affected objects. Full cache clears are simple but throw away every stored page, which pushes the whole load back onto Drupal at the moment you most need it to be quiet. Cache tag purging is the better fit when pages carry many cache tags, when a single node or taxonomy term appears in listings, menus and blocks, and when a full clear would cause a visible slowdown after each publish. Confirm with the Purge and Varnish purger project pages how tag-based invalidation is configured for your Drupal version, and test it on a copy of your real content model before you rely on it.

Ask three questions before the build starts. Which pages must never be stale, and how long is an acceptable delay between a publish and its appearance? Who owns the queue when a dispatch fails, and how will you know? And which traffic is authenticated, since logged-in pages and forms usually bypass the proxy and need their own plan. A partner should be able to show your measured baseline, a list of cache tags that matter to your content, and a written plan for failed purges. If those are missing, the Varnish layer will be hard to trust and the work will cost more to fix later.

Which Purge configuration fits which site

This table compares the main Purge and Varnish choices, from how queued invalidations are processed to whether a CDN sits in front of Varnish. Read each row against your traffic pattern, team capacity and how often editors change content, then use the trade-off column to see what you accept with each option.

DecisionOptionTrade-offChoose it when
Queue processingPurge on cronSimple to run, but invalidations wait for the next cron pass and cron timing can overlap on multi-server sitesContent changes are infrequent and a short delay before pages refresh is acceptable
Queue processingDedicated queue workerInvalidations run close to real time, but a worker process must be supervised and monitoredEditors expect changes live quickly or the site publishes often
Invalidation scopeCache tag purgingPrecise: only pages that carry affected tags are cleared, but Drupal must emit complete cache tags on every pagePages have many entities and broad URL purges would clear too much traffic
Invalidation scopeURL purgingEasy to reason about, but lists and aggregated pages are easy to miss and purges can be broader than neededSite structure is small and pages map cleanly to known URLs
Varnish topologySingle Varnish instanceLowest operational overhead, but one node is a single point of failure and capacity ceilingTraffic fits one host and downtime can be covered by a fast restore plan
Varnish topologyVarnish cluster with a purger per nodeResilient and scalable, but every node must receive purges and VCL must be kept identical across nodesTraffic or availability needs justify multiple nodes and a team can run the cluster
Edge layerVarnish aloneFewer components to run, but global latency and TLS termination remain on your own infrastructureAudience is concentrated in one region and infrastructure you control serves it well
Edge layerVarnish behind a CDNBetter edge reach, but cache rules and purge requests must be coordinated across two cache layersAudience is distributed or the CDN already handles TLS and DDoS protection in your estate

How to set up Varnish with the Purge module

This sequence puts Varnish in front of an existing Drupal site and connects it to cache tag invalidation, so that editing one node clears only the pages that display it. The result is a tested stack where anonymous pages are served from Varnish and purges reach it reliably through the queue.

  1. Confirm Drupal and Purge compatibility

    Before installing anything, check the Purge module's project page on Drupal.org against your Drupal core version, PHP version and the Varnish release your team runs. Confirm the PHP version your hosting platform provides meets the minimum for your Drupal release, using the PHP requirements page as the reference. Record the chosen versions in the build notes. This step is done when the team has a written compatibility matrix that the platform owner has signed off, and no module in the stack is flagged as unsupported for that core version.

  2. Install Purge and the Varnish purger

    A developer adds Purge and the Varnish purger module to the codebase with Composer, so the versions are pinned in the lock file and deployed the same way as the rest of the site. Enable the modules in a non-production environment and confirm that the Purge configuration page lists a Varnish purger under the purgers tab. This step is done when the modules appear in the configuration, the lock file is committed and the change passes review in version control.

  3. Set backend and Varnish host addresses

    Configure the purger with the addresses Drupal uses to reach Varnish, including the host name or IP and port for each Varnish node, and the address Varnish uses to reach the Drupal backend. Where several Varnish nodes sit behind a load balancer, list every node so each receives the purge request. Ask the infrastructure team to confirm which network path purge requests take, since firewalls and internal load balancers often change it. This step is done when a manual purge request from Drupal returns a successful response from each configured node in the logs.

  4. Write VCL that honors cache tags

    Varnish needs custom VCL to read the cache tag headers Drupal sends, store them with the cached object and handle purge requests from the purger. The VCL should restrict who may send purge requests to the Drupal servers only, and should pass through or ignore cookies according to your authenticated traffic plan. Have a Varnish specialist review the file, then load it on a test node and confirm the response carries the expected cache tag and age headers. This step is done when the VCL compiles, a cached page returns its tag headers, and a purge from an unauthorized address is refused.

  5. Enable and run the queue processor

    Purge queues invalidation requests and processes them later, so a queue processor must run on a schedule or as a worker. Choose the processor that fits your hosting model, whether cron, a Drush command in a scheduled job or a worker in the container platform, and make sure only one instance processes the queue at a time. Confirm the queue drains after content changes. This step is done when queued items move to processed within the interval your team sets, and the queue does not grow between runs.

  6. Verify tag-based purges with a test node

    Load a test node in a browser through Varnish and note its response headers. Edit the node, save it, then reload a listing page that shows it. The listing should refresh with the updated title while unrelated pages stay cached. Repeat with an authenticated session to confirm personalized responses are not stored for anonymous visitors. This step is done when the edited node and its listing pages update within the queue interval, unrelated pages keep their cache hits, and the authenticated check passes in a written test record.

  7. Document the purge runbook for operations

    Write a short runbook covering the purger configuration, the VCL location, the queue processor schedule, the node addresses and the steps for a full cache flush. Include the check for stuck queues and the owner for each item. Hand this to the team that operates the site so changes to Varnish or Drupal are tested against the same checks. This step is done when the operations team has walked through the runbook and can repeat the verification test without help.

What the VCL must do for cache tag purging to work

The VCL is where cache tag purging either works or quietly fails, so the first decision is to treat it as application-aware configuration rather than a generic caching template. Varnish has to do four things: accept invalidation requests only from trusted sources, keep the cache tag header that Drupal sends with each response, ignore cookies that do not change anonymous output, and hand authenticated traffic straight to the origin. Each of these maps to a specific part of the Purge module's Varnish integration, and each has a failure mode that looks like success in a browser. A purge request that is accepted from an untrusted network is a denial-of-service path, and a missing tag header means content edits never reach the cache.

Purge requests should be limited to the Drupal application servers or the purge worker's network range, typically through an ACL that Varnish checks before it runs the purge logic. Responses must keep the cache tag header Drupal emits, and the VCL must store it so Varnish can match a tag to the objects it holds. The configuration should also strip or ignore tracking parameters and cookies on anonymous requests, so that one visitor's analytics cookie does not split the cache into thousands of copies. For logged-in users, including editors, the VCL should pass the request to the origin when a Drupal session cookie is present, because a shared cached page can leak personalized content. Confirm the exact cookie names your site sets, since they depend on the session and any consent tools in use.

Have a Varnish-experienced engineer review the final VCL against the Purge module documentation and the Varnish version you run, and confirm the expected behavior with test cases: an anonymous page is cached and purged by tag after an edit, a logged-in request is never served from cache, and a purge request from outside the trusted range is refused. Varnish syntax and the purger's required headers change between releases, so the review should happen on the versions you will actually deploy and again after upgrades. Ask the partner or internal team to document each VCL rule with its reason, because the people who maintain the file later will need to know which cookies are safe to drop and why.

Handling authenticated traffic and personalized blocks

Varnish serves anonymous pages from memory, which is fast, but any response that depends on who is asking must be kept out of that shared store. The cards below cover the decisions that keep logged-in users, forms and personalized fragments correct while the anonymous cache stays effective.

Logged-in users bypassing cache

Drupal sends cache-friendly responses to anonymous visitors only. Authenticated requests need a VCL rule that passes them to the origin, otherwise one user's page can be served to everyone. Confirm which request cookies identify a session, which paths (admin, user, checkout) must always pass, and how the team will test that a logged-in request is never answered from cache. Expect to revisit this rule whenever the login or session setup changes.

Session cookies and the cache boundary

Drupal sets a session cookie when a user logs in, and Varnish must decide what to do with it. Stripping or ignoring cookies that Drupal does not need lets anonymous pages stay cached, while removing a session cookie that Drupal does need breaks logins. Confirm the exact cookie names used by the site, whether any third-party analytics or consent cookies reach Varnish, and how the VCL normalizes them before the cache lookup.

ESI and hole-punching for personalized fragments

A page that is mostly public but has a personal block, such as a greeting or cart count, can be cached with the personal part filled in by a separate request. Edge Side Includes or hole-punching, where Varnish fetches a fragment from the origin on each request, let the page stay cached. Confirm which blocks are personal, how many fragments a page carries, and whether the extra origin requests on every view are acceptable for the traffic profile.

Cache contexts for roles and permissions

Drupal's cache contexts, such as user roles, permissions and language, tell the render cache when output varies. These contexts matter at the edge only if the proxy can see the same variation, so a page that differs by role needs either a separate cache entry or a pass to origin. Confirm which contexts the site's custom code and contributed modules add, and whether any of them vary responses that Varnish caches for anonymous users.

Forms and CSRF tokens

Forms carry per-session CSRF tokens, and a cached form can hand one visitor a token belonging to another, causing failed submissions or, in the worst case, requests that run under the wrong session. Confirm that form routes and any page embedding a form bypass the cache or receive the token through a fragment, and test a submission from a cached page. Check each custom form the site ships for this behavior.

Per-user data leaking through cached responses

The most serious failure is a response that contains one user's name, email or order detail being stored and served to other visitors. It happens when a personal block is cached without a cache tag or context, or when headers such as Set-Cookie or Cache-Control are misconfigured. Confirm that the origin sends accurate cache metadata, that Varnish never caches responses that set cookies, and that the team runs a test that compares anonymous and authenticated responses on key pages.

Questions teams ask before building Varnish and Purge

What does a Varnish and Purge build cost and what drives the effort?

The cost is mostly the time of engineers who design the caching layer, write and test the VCL, configure the Purge module and verify invalidation on real content. Effort rises with the number of sites behind the cache, the number of content types that must purge correctly, how many distinct cache tags the pages carry, and how many routes need special handling such as search, forms or personalized blocks. Ongoing costs come from running Varnish servers, monitoring the purge queue and updating VCL when Drupal or Varnish changes. Ask any provider for a written scope that lists sites, hosts, purge triggers, and test cases, because a quote built on those inputs is the only fair comparison.

How long does it take to scope and build Varnish with Purge?

Scoping usually comes first and depends on how well your team understands the current caching behavior. Scoping covers reviewing which pages are cacheable, which cookies and headers vary responses, and which content changes must clear which pages. The build then depends on the number of environments, the VCL complexity, the purge integration, and the testing needed to prove that an edited node clears the right listing pages and feeds. Delays most often come from unclear ownership of the edge, late access to staging hosts, and authenticated pages that need a decision before coding starts. Ask for a timeline tied to named milestones rather than a single end date.

What must our team provide before a Varnish and Purge project starts?

Several inputs decide whether the work can proceed without stalls. You need access to the Drupal sites, their hosting and web server configuration, and the current reverse proxy or load balancer. You need a named owner for VCL who can approve changes, and someone who knows which cookies, headers and sessions the application uses. Test data matters: a staging copy with realistic content types, menus, taxonomies and a representative set of user roles lets engineers prove invalidation works. You also need the list of content events that must purge pages, such as publishing, unpublishing, menu changes and taxonomy edits. Confirm these items in writing at the start of the engagement.

Can our in-house team build Drupal caching with Varnish alone?

An experienced Drupal and operations team can build this in-house if it has someone who understands Drupal's cache metadata, cache tags and the Varnish request lifecycle, plus time to test edge cases. The risk is rarely the first working configuration. The risk is the less visible cases: a block that carries a user-specific cache context, a view that does not expose its tags, or a VCL rule that caches a page for an authenticated user. Teams that build in-house often benefit from an outside review of the VCL and purge test plan before production. Decide early who will carry the setup after launch, because the knowledge sits in configuration, not in a document most people read.

How do you keep the Purge queue reliable in production?

Reliability depends on processing purge requests in a way that is ordered, observable and recoverable. Purge stores invalidation requests in a queue, and a processor must run regularly on every host that needs the change, so the queue is worked by a scheduled job or worker that is monitored. Engineers should watch the queue length, the age of the oldest item, and failed purge responses, and alert when any of them grow. Avoid overlapping runs of the same processor. Test what happens when Varnish is restarted, when one node is unreachable, and when a large batch of content is edited at once. Document the recovery steps so an operator knows how to flush or replay the queue.

How do authenticated users and sessions affect the Varnish setup?

Authenticated traffic is the area where caching mistakes cause the most damage, because a page built for one user can be served to another. The VCL must pass requests that carry session cookies to the origin, and Drupal must send correct cache headers and cache contexts so that personalized output is never stored at the edge. Many teams cache only anonymous pages at Varnish and leave logged-in traffic to Drupal's own cache. Whichever route you choose, test with multiple roles, log out and log in flows, and forms that set cookies. Security review should confirm that no personal data appears in a cached response.

How do Drupal and Varnish upgrades change the caching setup?

Upgrades change the caching setup in two ways. A Drupal upgrade can alter cache metadata, module behavior and the tags emitted by views or blocks, so the purge test cases must be rerun after each upgrade. A Varnish upgrade can change VCL syntax, default behavior or the purge interface, which means the VCL must be checked against the new release before deployment. Keep the VCL, purge configuration and test scripts in version control so changes are reviewable. Drupal core releases follow a published schedule, and the Drupal core release schedule helps you plan when a version change will arrive. Confirm supported Varnish versions with the vendor before you commit to an upgrade window.

Security and operational risks of a Varnish layer

Putting Varnish in front of Drupal moves part of the security boundary and part of the cache logic out of Drupal. The cards below cover the exposures that come with that move and the monitoring and recovery steps that keep a purge-driven cache correct over time. Each one should be checked against your own hosting setup before the design is signed off.

Purge endpoint exposure

The Varnish purger sends cache invalidation requests to Varnish over HTTP, so the endpoint that accepts them is a control point. If it is reachable from the public internet, anyone who can send a crafted request can empty parts of your cache and push load onto Drupal. Confirm that Varnish only accepts purge requests from the Drupal web tier, that the ACL in the VCL is enforced at the listener your hosting setup actually uses, and that load balancers or ingress controllers do not forward PURGE requests from outside.

Cache poisoning through unkeyed headers

Varnish builds its cache key from the URL and host by default, so any request header that changes the response but is not part of the key can let one visitor's response be served to others. Typical examples are cookies, language or device headers, and forwarded headers set by a proxy. Review every header Drupal varies on, normalize or strip the ones you do not need in vcl_recv, and test the cache with requests that differ only in headers that should not change the page.

Leaking authenticated pages

Pages built for logged-in users carry personal data, and a shared cache can serve them to anonymous visitors if the request is cached without checking the session. Drupal sends Cache-Control and Vary headers, but a VCL that ignores session cookies or caches responses with Set-Cookie can override them. Confirm that the VCL passes requests with session cookies straight to the backend, that responses for authenticated users are not stored, and that a test account sees its own content after purges.

Monitoring Varnish and the purger

A Varnish layer can fail quietly. Hit ratio can fall, backends can be marked sick, and purge requests can start returning errors while the site still loads. Track cache hit ratio, backend health, and purge response codes as separate signals, and record which purger instance handled each invalidation. Confirm which metrics your hosting platform exposes for Varnish and how alerts reach the team that owns the site.

Queue backlog alerts

With the Purge module, invalidation requests are queued in Drupal and processed by a worker, so content can stay stale while the queue grows. A stuck or slow processor means editors see old pages after publishing, and the problem is easy to miss because the site still responds. Set an alert on queue length and on the age of the oldest queued item, and confirm how the processor is triggered on your cron or worker setup so it does not overlap with other jobs.

Restoring the cache after a restart

Varnish keeps its cache in memory or in a storage file, so a restart or a node replacement starts with an empty cache. Every request then reaches Drupal until the cache fills, which can overload the database and PHP workers on a busy site. Decide ahead of time whether the cache is rebuilt by traffic, by a warming job, or by a rolling restart across nodes, and confirm that the purge queue is not reset in a way that leaves stale pages in a new cache.

What DeployOpen delivers and what your team keeps

A fixed-scope Varnish and Purge engagement produces a defined set of artifacts, agreed in writing before work starts. The scope document records which Drupal sites, hostnames, content types and cache tags are in the Varnish path, which purger instances are configured, and which traffic is excluded. The VCL is the Varnish configuration for your environment, including backend definitions, the purge handling in vcl_recv and vcl_purge, the cache-tag response headers, and the rules that keep authenticated sessions and cookies out of the shared cache. The Purge configuration covers the Drupal side: the purger instance, the queue processor settings, the cache tag headers and the invalidation behavior for each content change. A test plan shows how each cache rule and purge path was exercised, and a runbook explains how operators check queue depth, flush the cache, roll back VCL and respond to a purge that did not reach the cache.

Your team owns these artifacts after handover. They live in your repositories and change control, not in a DeployOpen-hosted system, so your engineers can edit the VCL, adjust purge settings and rerun the test plan without us. Plan for ownership of the Varnish service itself, its sizing, its TLS termination and its access controls, along with the monitoring that tells you when the purge queue is backing up. Ask any partner to confirm in writing which of these items are delivered, in what format, and which versions of Varnish, Drupal and the Purge modules they were tested against. Also confirm how the Varnish configuration is kept under version control and who approves changes to it. Ongoing support, upgrades and continuous testing are available as separate retainers, so the handover should state clearly which of these your team will take on and which may be contracted later.

How DeployOpen scopes and supports Varnish and Purge

DeployOpen plans, builds, documents and supports self-hosted Drupal platforms inside your own infrastructure, including Varnish in front of Drupal and cache tag purging with Purge. Engagements start with a written scope so that caching behavior, invalidation rules and handover responsibilities are agreed before configuration begins.

How we scope

  • We map which pages are anonymous, which are personalized and which must never be cached at the edge.
  • We list the content events that should purge specific cache tags, and the pages each event must refresh.
  • Engagements are fixed-scope, with deliverables and timelines agreed in writing before work starts.

How we build

  • We write and review the VCL for your Varnish version, covering cookies, cache keys and purge requests.
  • We configure the Purge queue and Varnish purger, then test cache tag invalidation against real content changes.
  • We check authenticated traffic paths, so logged-in responses are never served to anonymous visitors.

How we hand over

  • We document the VCL, purger settings, queue processing setup and the cache tag map for your team.
  • We record the test cases used for purging and cache bypass, so your team can rerun them after changes.
  • We walk your operators through queue monitoring, failure handling and the steps for a manual purge.

How we support

  • Ongoing support, Drupal and Varnish upgrades and continuous testing are available as retainers.
  • We review purge behavior after Drupal core and contributed module updates, which can change cache tags.
  • Confirm with your Varnish and hosting teams which Varnish release, VCL features and support terms apply to your environment.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.