How to Configure Varnish Cache for Magento 2

Varnish is a high-performance HTTP reverse proxy that sits in front of Magento and serves cached pages without hitting the PHP backend. With a properly tuned Varnish setup, stores routinely achieve 85%+ cache hit rates, meaning the vast majority of page requests are served directly from memory in under 10 milliseconds.

How Varnish Works with Magento

Magento generates a VCL (Varnish Configuration Language) file that tells Varnish which pages to cache, how to vary cache entries, and when to purge stale content. The key mechanism is the X-Magento-Vary cookie, which Magento sets on every response.

The X-Magento-Vary Cookie

This cookie is a hash of the visitor's context: customer group, selected currency, and store view. Varnish uses it to serve different cached versions of the same URL to different visitor segments.

For example, a product page at /product-a.html might have separate cached versions for:

  • Guest visitors (NOT LOGGED IN group, USD)
  • Wholesale customers (WHOLESALE group, USD)
  • European visitors (NOT LOGGED IN group, EUR)

This is core Magento architecture -- do not attempt to disable or modify the X-Magento-Vary cookie behavior.

Generating the VCL Configuration

Magento can generate a Varnish VCL file from the admin panel:

  1. Go to Stores → Configuration → Advanced → System → Full Page Cache
  2. Set Caching Application to "Varnish Cache"
  3. Click Export VCL for your Varnish version (6.x or 7.x)
  4. Save the generated .vcl file and load it into Varnish
# Test VCL syntax
varnishd -C -f /etc/varnish/default.vcl

# Reload VCL without restart
varnishadm vcl.load new_config /etc/varnish/default.vcl
varnishadm vcl.use new_config

Cookie Handling

Cookies are the most common cause of low cache hit rates. Every unique cookie value in the request creates a different cache entry. Analytics and tracking cookies must be stripped from requests before they reach Varnish's cache lookup.

Cookies to Exclude (Strip from Requests)

These cookies should be removed in VCL before cache hash computation:

  • _ga, _gid, _gat -- Google Analytics
  • _fbp, _fbc -- Facebook Pixel
  • __utma, __utmb, __utmc, __utmz -- Google Analytics (legacy)
  • _hjid, _hjSession -- Hotjar
  • Any other analytics or tracking cookies

Cookies to NEVER Exclude

These cookies affect page content and must be included in the cache key:

  • form_key -- CSRF protection, required for form submissions
  • private_content_version -- triggers private content (mini-cart, customer name) loading via AJAX
  • store -- current store view selection
  • currency_code -- selected currency (changes displayed prices)
  • X-Magento-Vary -- composite context hash used as cache key

Stripping any of these cookies will cause incorrect page content to be served to visitors.

Example VCL Cookie Stripping

In the vcl_recv subroutine of your VCL:

sub vcl_recv {
    # Remove tracking cookies before cache lookup
    if (req.http.Cookie) {
        set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_ga|_gid|_gat|_fbp|_fbc|__utm[a-z]+|_hj[a-zA-Z]+)=[^;]*", "");
        # Clean up empty/malformed cookie header
        set req.http.Cookie = regsuball(req.http.Cookie, "^;\s*", "");
        if (req.http.Cookie == "") {
            unset req.http.Cookie;
        }
    }
}

Cache Warming with Varnish

Cache warmers send HTTP requests to pre-populate the Varnish cache after it has been purged. Since cache warmers operate server-side via standard HTTP requests, they are fully compatible with Varnish -- the warmer's requests go through Varnish just like any visitor request.

With an 85% FPC hit rate, the load from cache warming (prefetch) is negligible on the origin server because Varnish serves the cached response for the majority of repeated requests.

AJAX Endpoint Collisions

Cache warmers should not attempt to warm AJAX endpoints that return dynamic, per-session data. Exclude URL patterns like:

  • customer/section/load
  • checkout/cart
  • rest/V1/
  • Any custom AJAX endpoints returning personalized data

Most cache warmer tools support regex-based URL exclusion to filter these patterns from the warming queue.

Cache Clearing

When content changes, Magento sends purge requests to Varnish for the affected URLs. For a full cache reset, follow this order:

  1. php bin/magento cache:clean -- clears Magento cache tags
  2. php bin/magento cache:flush -- flushes Magento cache storage
  3. redis-cli FLUSHALL -- clears Redis (if used as backend)
  4. varnishadm "ban req.url ~ /" -- purges all URLs in Varnish

Clearing Varnish completely should be done sparingly. Tag-based purging (which Magento does automatically on content changes) is preferred because it preserves the cache for unaffected pages.

Monitoring Cache Performance

Use varnishstat to monitor hit rates:

varnishstat -1 | grep -E "MAIN.cache_hit|MAIN.cache_miss"

A healthy Magento+Varnish setup should show 80–95% hit rate. If the hit rate is low, check:

  • Cookie stripping (most common issue)
  • Vary response headers adding unnecessary variation
  • Low TTL values in VCL
  • Frequent full purges

Use varnishlog to debug individual requests:

varnishlog -q "ReqURL eq '/product-page.html'"
Loading...