Caching · Varnish
Varnish Configuration for Magento
Magento ships first-class Varnish support. Configured correctly, it cuts TTFB by another 50–70% beyond Redis and absorbs traffic spikes that would otherwise crash the application.
Varnish is the recommended HTTP-level cache for Magento 2. Where Redis caches Magento's internal state (configuration, layout, blocks, sessions), Varnish caches the rendered HTML of cacheable pages and serves them without ever touching PHP. Configured correctly it produces a TTFB in the 30–80 ms range — a 5–10× improvement over the same store served by PHP-FPM with Redis.
Generate the VCL from Magento itself
Magento generates a VCL (Varnish Configuration Language) file tailored to its caching expectations:
php bin/magento varnish:vcl:generate \
--access-list=localhost \
--backend-host=127.0.0.1 \
--backend-port=8080 \
--output-file=/etc/varnish/default.vcl \
--grace-period=300 \
--export-version=6The export-version flag should match your installed Varnish major version. Magento's generated VCL handles cache-tag invalidation, ESI request routing, and the X-Magento-Vary header that distinguishes cacheable variants (currency, customer group, store view).
Configure Magento to issue cache-tag headers
In Stores → Configuration → Advanced → System → Full Page Cache, set Caching Application to 'Varnish Cache'. Magento will then emit X-Magento-Tags response headers on cacheable pages. Varnish's generated VCL uses those tags for fine-grained invalidation — so flushing the cache for a single product invalidates only that product's pages rather than the entire site.
Most common Varnish problems
- Set-Cookie on cacheable pages — Magento sets a cookie on first visit that, if it leaks into a cacheable response, forces Varnish to never cache that page. Magento's generated VCL strips the relevant cookies, but custom modules sometimes set additional cookies that re-trigger the un-cacheable state.
- BAN/PURGE permission denied — Magento issues BAN requests against Varnish to invalidate cached entries. If the access-list parameter to varnish:vcl:generate doesn't include the application server's IP, the BAN requests are silently rejected and the page cache becomes stale within minutes of any catalog change.
- Wrong port routing — A common deploy pattern is Varnish on port 80 in front of Nginx on port 8080 in front of PHP-FPM. If Nginx isn't binding 8080 (or Magento was configured with backend-port=80 by mistake), Varnish fails to forward requests to the application.
Verifying it's working
Hit a product page twice and check the response headers. The first request should produce 'X-Magento-Cache-Debug: HIT' (or MISS on first ever) plus 'Age: 0' from Varnish. The second request should produce 'Age: