Introduction: why Magento 2 without Varnish is a bottleneck
We integrate Varnish with Magento 2 to achieve up to 50x speed increase and reduce server load by 10-50x, saving up to $10,000 per month on hosting costs. For a typical store with 10,000 products, Varnish saves $7,500/month in hosting costs. Magento 2 is a heavy CMS: each page is generated dynamically via PHP-FPM and MySQL. With 500+ concurrent visitors, CPU hits 100% and response time exceeds 5 seconds, leading to lost conversions. Varnish solves this: it caches ready HTML pages in RAM and serves them in microseconds. Server resource savings reach up to 70%, and hosting costs drop by 3-5 times. On one project with 50,000 products, hit rate increased from 40% to 93% after VCL tuning. We configure Varnish for your project with a guaranteed hit rate of 85-95%. Get a consultation — we evaluate your project in one day.
How Varnish accelerates Magento 2
Varnish stores cache in RAM (-s malloc), which is 100x faster than file or Redis cache. This is essential for full-page caching in Magento 2. Even during full invalidation (bulk price updates), Varnish warms up in 1-2 minutes thanks to grace (serving stale copies) and saint mode (skipping broken backends). This is critical for e-commerce stores with peak loads: without Varnish, the server can't handle even 10% of planned traffic.
Why standard VCL requires refinement
Magento generates VCL via admin, but it fails to handle:
- passing real IP via X-Forwarded-For;
- processing BAN requests with tag patterns;
- caching for HTTP/HTTPS via
Ssl-Offloadedheader; - URL normalization (UTM tags, fbclid).
A typical mistake: ACL for PURGE and BAN is not configured — invalidation doesn't work and site changes are not reflected. Our engineers fix VCL for each task.
How we set up Varnish: installation, VCL, and ESI
Installation and basic parameters
# Installation on Ubuntu LTS (latest version)
curl -s https://packagecloud.io/install/repositories/varnishcache/varnish74/script.deb.sh | sudo bash
apt install varnish
# Service file (edit via systemctl edit varnish)
ExecStart=
ExecStart=/usr/sbin/varnishd \
-a :80 \
-T localhost:6082 \
-f /etc/varnish/default.vcl \
-s malloc,2g \
-p thread_pools=2 \
-p thread_pool_max=1000 \
-p thread_pool_timeout=300
Allocate 2-4 GB malloc for Magento. Less than 1 GB is ineffective: pages weigh 80-200 KB, and with a small cache, hit rate drops.
Key parts of the corrected VCL
vcl 4.1;
import std;
backend default {
.host = "127.0.0.1";
.port = "8080";
.connect_timeout = 600s;
.first_byte_timeout = 600s;
.between_bytes_timeout = 600s;
}
acl purge {
"localhost";
"127.0.0.1";
}
sub vcl_recv {
# Pass real IP
if (req.restarts == 0) {
if (req.http.X-Forwarded-For) {
set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
} else {
set req.http.X-Forwarded-For = client.ip;
}
}
# PURGE requests from Magento
if (req.method == "PURGE") {
if (!client.ip ~ purge) {
return (synth(405, "Not allowed"));
}
return (purge);
}
# BAN by X-Magento-Tags (block invalidation)
if (req.method == "BAN") {
if (!client.ip ~ purge) {
return (synth(405, "Not allowed"));
}
if (req.http.X-Magento-Tags-Pattern) {
ban("obj.http.X-Magento-Tags ~ " + req.http.X-Magento-Tags-Pattern);
}
return (synth(200, "Banned"));
}
# Don't cache checkout, cart, customer pages
if (req.url ~ "/(checkout|customer|account|cart|wishlist)") {
return (pass);
}
# Remove cookies on static files
if (req.url ~ "\.(css|js|png|jpg|jpeg|webp|gif|ico|woff2|svg)(\?.*)?$") {
unset req.http.Cookie;
return (hash);
}
# Clean UTM and other tracking parameters
set req.url = regsuball(req.url, "(^|&)(utm_[a-z]+|gclid|gclsrc|fbclid)=[^&]*", "");
set req.url = regsub(req.url, "^(.*)\?&?(.*)?$", "\1?\2");
set req.url = regsub(req.url, "^(.*)\?$", "\1");
return (hash);
}
sub vcl_hash {
hash_data(req.url);
if (req.http.host) {
hash_data(req.http.host);
} else {
hash_data(server.ip);
}
if (req.http.Ssl-Offloaded) {
hash_data(req.http.Ssl-Offloaded);
}
return (lookup);
}
sub vcl_backend_response {
if (beresp.status >= 500) {
set beresp.uncacheable = true;
set beresp.ttl = 1s;
return (deliver);
}
if (beresp.http.content-type ~ "text/html") {
set beresp.ttl = 1d;
set beresp.grace = 1h;
}
if (bereq.url ~ "\.(css|js|woff2)(\?.*)?$") {
set beresp.ttl = 1y;
}
if (beresp.ttl > 0s) {
unset beresp.http.Set-Cookie;
}
return (deliver);
}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
set resp.http.X-Cache-Hits = obj.hits;
} else {
set resp.http.X-Cache = "MISS";
}
unset resp.http.X-Magento-Tags;
unset resp.http.X-Powered-By;
unset resp.http.Server;
return (deliver);
}
ESI — dynamic blocks inside cached pages
Magento uses ESI (Edge Side Includes) for personalized blocks (cart, user name). In VCL, ESI is enabled via beresp.do_esi = true, which Magento sets with header X-Esi: 1. Verify:
curl -I <your-store-url>/ | grep X-Cache
# Expected: HIT
curl -I <your-store-url>/checkout/cart/ | grep X-Cache
# Expected: MISS (cart not cached)
Comparison of Varnish and Magento's built-in cache
| Parameter | Varnish | Built-in (Files/Redis) |
|---|---|---|
| Storage | RAM | Files or Redis |
| Delivery speed | microseconds | milliseconds |
| Invalidation | by X-Magento-Tags (BAN) | by tags (full flush) |
| Hit rate | 85-95% | 70-80% |
| Grace/saint mode | + | - |
Varnish is 3-5x faster and achieves 15-20% higher hit rate.
Common mistakes and their solutions
| Problem | Symptom | Solution |
|---|---|---|
| Hit rate < 70% | Many MISS in logs | Check cookie blocking, increase malloc size, remove unnecessary cookies from cacheable requests |
| Invalidation not working | Page remains old after product update | Check ACL for PURGE/BAN; ensure BAN requests are reaching Varnish |
| ESI not updating | Cart shows outdated data | Check that VCL does not remove X-Esi header; ESI blocks should be for dynamic content only |
Process and timelines
- Audit of current architecture (VCL, Nginx, PHP-FPM).
- Installation and configuration of Varnish with optimal malloc and thread_pools.
- Adapt VCL for Magento (ESI, BAN, grace).
- Configure SSL termination (Nginx/HAProxy) with
Ssl-Offloadedheader pass. - Integrate with Magento: select Varnish in admin, enable full-page cache.
- Test hit rate (target 85-95%) and invalidation.
- Document and train on basic operations (
varnishadm,varnishlog). - One month support after setup.
Timelines: installation and basic configuration — 1-2 days, testing and optimization — 1 day, load testing — 0.5-1 day.
What's included
- Full audit and parameter selection.
- Installation, VCL, ESI, HTTPS configuration.
- Integration with Magento and invalidation verification.
- Team training.
Our engineers have 10+ years of experience with Magento and Varnish, and have completed over 50 projects with peak loads up to 10,000 RPS. We guarantee a hit rate of 85-95% or we adjust for free. Order Varnish setup for your Magento 2 — get a consultation within 1 day. Contact us to discuss your project.







