PHP / Magento Dev Blog

  • Publikacje
  • O autorze
  • Kontakt

Varnish – VCL, cache tagging, ESI, invalidation, DDEV setup

by Henryk Tews / Tuesday, 13 October 2020 / Published in Magento 2, Środowiska

Magento’s built-in Full Page Cache stores pages in files or Redis. It works, but it handles requests inside PHP – nginx and PHP-FPM still have to start for every request. Varnish sits in front of nginx and serves pages from memory without touching PHP. For a shop with traffic that is the difference between a second and milliseconds.

How Varnish works with Magento 2

Stack without Varnish: Browser – nginx – PHP-FPM – Magento – Redis/file cache

With Varnish: Browser – Varnish – (cache HIT: immediate response) or (cache MISS: nginx – PHP-FPM – Magento)

Varnish holds pages in RAM. A cache HIT is literally a few milliseconds – Varnish fires no PHP process. A cache MISS goes to the backend (nginx + PHP), which generates the page and hands it to Varnish for caching.

Configuring Magento for Varnish

# Enable Varnish as the FPC engine
bin/magento config:set system/full_page_cache/caching_application 2

# Generate the VCL configuration file for Varnish
bin/magento varnish:vcl:generate \
    --backend-host=nginx \
    --backend-port=80 \
    --export-version=6 \
    --output-file=/etc/varnish/magento.vcl

VCL basics – how Varnish makes decisions

# Fragment of magento.vcl - simplified for readability

sub vcl_recv {
    # Do not cache requests from logged-in customers
    if (req.http.cookie ~ "PHPSESSID" && req.http.cookie ~ "customer_logged_in") {
        return (pass);
    }

    # Do not cache POST requests
    if (req.method == "POST") {
        return (pass);
    }

    # Normalise URL - remove tracking parameters
    if (req.url ~ "(\?|&)(utm_source|utm_medium|utm_campaign|gclid)=") {
        set req.url = regsuball(req.url, "&(utm_source|utm_medium|utm_campaign|gclid)=[^&]+", "");
    }

    return (hash);
}

sub vcl_backend_response {
    # Cache product page for 1 hour
    if (bereq.url ~ "^/catalog/product/view") {
        set beresp.ttl = 1h;
    }
    # Home page - 5 minutes
    if (bereq.url == "/") {
        set beresp.ttl = 5m;
    }
}

Cache tagging and invalidation

Magento tags every page with an X-Magento-Tags header containing identifiers of the entities used on that page. When a product changes, Magento sends a PURGE request to Varnish with that product’s tag – Varnish removes from cache all pages containing that tag:

<?php

namespace Vendor\Module\Model;

use Magento\CacheInvalidate\Model\PurgeCache;
use Magento\Framework\App\Cache\Tag\Resolver;

class ProductCacheInvalidator
{
    public function __construct(
        private PurgeCache $purgeCache,
        private Resolver $tagResolver
    ) {}

    public function invalidateProduct(\Magento\Catalog\Model\Product $product): void
    {
        $tags = $this->tagResolver->getTags($product);
        $this->purgeCache->sendPurgeRequest(implode('|', $tags));
    }
}

ESI – dynamic blocks on cached pages

Problem: the product page is cached, but the “Recently viewed” block is per-user. ESI (Edge Side Includes) solves this through separate caching of blocks:

<!-- Varnish replaces this tag with a separate backend request -->
<esi:include src="/page_cache/block/esi/blocks/" />

Varnish in DDEV

# .ddev/docker-compose.varnish.yaml
version: '3.6'
services:
  varnish:
    image: varnish:6.4
    ports:
      - "6081:6081"
    volumes:
      - ./magento.vcl:/etc/varnish/default.vcl
    environment:
      - VARNISH_SIZE=256m
    depends_on: [web]
    labels:
      com.ddev.site-name: ${DDEV_SITENAME}
# Varnish statistics
varnishstat

# Real-time logs
varnishlog -q "ReqURL ~ '/catalog/product'"

# Manual PURGE of entire cache
curl -X PURGE http://localhost:6081/.*

# Check if a page came from Varnish
curl -I https://magento2-dev.ddev.site/ | grep X-Cache
# X-Cache: HIT or MISS

Summary

Varnish is one of the biggest performance improvements you can make for a Magento shop under load. A cache HIT eliminates PHP from handling the request entirely. The key is a good understanding of VCL and the tagging mechanism – then you can precisely control what is cached and for how long, without the risk of serving stale data.

About Henryk Tews

What you can read next

OpenTelemetry – distributed tracing, auto-instrumentation, Jaeger in DDEV
DDEV – local Magento 2 in 10 minutes, comparison with XAMPP
Docker Compose production – full Magento 2 stack, secrets, health checks, deployment

© 2026 Created by

TOP
Zarządzaj zgodą
Aby zapewnić jak najlepsze wrażenia, korzystamy z technologii, takich jak pliki cookie, do przechowywania i/lub uzyskiwania dostępu do informacji o urządzeniu. Zgoda na te technologie pozwoli nam przetwarzać dane, takie jak zachowanie podczas przeglądania lub unikalne identyfikatory na tej stronie. Brak wyrażenia zgody lub wycofanie zgody może niekorzystnie wpłynąć na niektóre cechy i funkcje.
Funkcjonalne Always active
Przechowywanie lub dostęp do danych technicznych jest ściśle konieczny do uzasadnionego celu umożliwienia korzystania z konkretnej usługi wyraźnie żądanej przez subskrybenta lub użytkownika, lub wyłącznie w celu przeprowadzenia transmisji komunikatu przez sieć łączności elektronicznej.
Preferencje
Przechowywanie lub dostęp techniczny jest niezbędny do uzasadnionego celu przechowywania preferencji, o które nie prosi subskrybent lub użytkownik.
Statystyka
Przechowywanie techniczne lub dostęp, który jest używany wyłącznie do celów statystycznych. Przechowywanie techniczne lub dostęp, który jest używany wyłącznie do anonimowych celów statystycznych. Bez wezwania do sądu, dobrowolnego podporządkowania się dostawcy usług internetowych lub dodatkowych zapisów od strony trzeciej, informacje przechowywane lub pobierane wyłącznie w tym celu zwykle nie mogą być wykorzystywane do identyfikacji użytkownika.
Marketing
Przechowywanie lub dostęp techniczny jest wymagany do tworzenia profili użytkowników w celu wysyłania reklam lub śledzenia użytkownika na stronie internetowej lub na kilku stronach internetowych w podobnych celach marketingowych.
  • Manage options
  • Manage services
  • Manage {vendor_count} vendors
  • Read more about these purposes
Zobacz preferencje
  • {title}
  • {title}
  • {title}