Varnish Cache is not just another web accelerator—it’s a purpose-built, high-performance HTTP reverse proxy cache engineered for speed, scalability, and operational precision. Unlike generic proxies or built-in web server caches, Varnish operates at the HTTP layer with near-zero latency overhead, consistently delivering sub-millisecond cache hits under extreme concurrency. In production environments handling 50,000+ requests per second, Varnish routinely achieves >95% cache hit ratios while sustaining median response times under 0.8 ms—figures validated by independent load tests at Wikimedia, The Guardian, and Spotify’s legacy infrastructure. This article cuts through marketing abstractions to explain what Varnish *is*, how it fundamentally differs from alternatives like NGINX caching or CDNs, and—most importantly—what measurable outcomes you can expect when deploying it correctly.
How Varnish Works: The HTTP-Centric Architecture
Varnish sits between clients (browsers, apps) and origin servers (Apache, Node.js, PHP-FPM). Its core innovation lies in its domain-specific language—Varnish Configuration Language (VCL)—which lets engineers write logic that executes *during* HTTP request processing, not before or after. When a request arrives, Varnish parses headers, evaluates cacheability rules in real time, checks its in-memory object store (using a highly optimized malloc-based allocator), and either serves a cached object or forwards the request upstream—all within a single event loop thread.
This contrasts sharply with traditional caching layers. NGINX, for example, relies on static cache keys and limited conditional logic; its proxy_cache_valid directives cannot inspect cookie values or dynamically rewrite cache keys based on device type or A/B test variants. Varnish, by contrast, exposes full access to request and response objects: req.http.User-Agent, beresp.http.Cache-Control, even req.url mutations mid-flow. That granularity enables precise cache partitioning—for instance, storing separate versions of a product page for logged-in users (with cart counts) versus anonymous visitors.
Varnish’s storage engine—malloc, file, or persistent (introduced in 6.0)—is tuned for low-latency memory access. Benchmarks show malloc storage delivers ~3× higher throughput than file-backed caching under random read workloads. Crucially, Varnish avoids disk I/O for cache lookups entirely; objects are memory-resident unless explicitly spilled (a rare occurrence in well-tuned deployments).
Varnish vs. Alternatives: A Reality-Based Comparison
Choosing a caching solution isn’t about features—it’s about matching architecture to traffic patterns, failure modes, and engineering velocity. The table below reflects empirical findings from third-party performance audits (2022–2024) across 17 high-traffic e-commerce and publishing platforms:
| Solution | Median Cache Hit Time | Max Sustained RPS (4-core) | Dynamic Key Support | Cache Purge Granularity | Real-World Cache Hit Ratio* |
|---|---|---|---|---|---|
| Varnish Cache 7.4 | 0.4–0.9 ms | 82,000 | Full (VCL-driven) | Per-URL, regex, ban expressions | 89–96% |
| NGINX Proxy Cache | 1.2–2.7 ms | 31,000 | Limited (key variables only) | Per-URL or cache zone only | 72–83% |
| Cloudflare CDN | 8–22 ms (edge-to-client) | N/A (edge network) | Basic (cookie/header presence) | Per-URL or prefix | 65–79% (origin offload) |
| Redis + Custom Layer | 2.1–4.8 ms | 44,000 | Full (application logic) | Per-key or pattern | 78–88% (requires app-level cache control) |
*Measured over 30-day production windows; excludes CDN-layer caching where applicable.
Note the decisive advantage in latency and throughput: Varnish’s user-space design eliminates kernel TCP stack traversal for cached responses. It also sidesteps the “cache stampede” problem common in application-layer caches via built-in grace mode—serving stale content while revalidating in background—without requiring custom locking logic.
Tip: Never useCache-Control: private as a blanket directive. Varnish respects RFC 7234 but allows VCL to override it safely—e.g., caching personalized fragments while excluding sensitive headers. Test with
curl -I and check
X-Varnish and
X-Cache headers.
Real-World Impact: The Guardian’s 72% Origin Reduction
In 2021, The Guardian migrated its high-traffic news homepage and article endpoints from a custom NGINX-based caching layer to Varnish 6.5. Prior to migration, their origin servers handled ~14,200 requests per second during peak breaking-news events, with CPU saturation above 92% and 400+ ms average response times. Post-migration, using VCL to segment cache by device type (mobile, tablet, desktop), geolocation (for local edition banners), and ad targeting segments, they achieved:
- A 72% reduction in origin requests during the UK election night coverage
- Median response time dropped from 382 ms to 47 ms
- Cache hit ratio sustained at 94.3% for 18 consecutive hours
- Zero origin failures despite a 3.1× traffic spike
Critically, this wasn’t accomplished with configuration defaults. Their VCL included dynamic TTL calculation based on content freshness signals (e.g., breaking news articles cached for 30 seconds, evergreen explainers for 24 hours), ban lists triggered by CMS publish hooks, and synthetic error pages served during origin downtime—proving Varnish’s resilience extends beyond raw speed.
Implementing Varnish: A Step-by-Step Production Checklist
Deploying Varnish successfully requires attention to HTTP semantics—not just syntax. Follow this sequence rigorously:
- Validate origin cache headers: Ensure your backend emits correct
Cache-Control,ETag, andVaryheaders. Runcurl -I https://yoursite.com/and verifyVary: Accept-Encoding, User-Agentexists if serving compressed or device-specific assets. - Start with a minimal VCL: Begin with the default
vcl_backend_responsethat setsberesp.ttl = 120sandberesp.grace = 1h. Do not add complex logic until baseline caching works. - Configure health probes: Define
probeblocks that check origin liveness on a critical endpoint (e.g.,/healthz) with timeout and threshold settings. Varnish will automatically shunt traffic from failed backends. - Enable logging and monitoring: Use
varnishlogto trace request flow andvarnishstatto trackMAIN.cache_hit,MAIN.cache_miss, andMAIN.n_lru_nuked. Alert on sustainedn_lru_nuked > 0—indicating memory pressure. - Test purge workflows: Implement ban expressions (e.g.,
ban(\"req.url ~ ^/products/ && req.http.host == example.com\")) and validate withvarnishadm ban.list. Avoidpurge()for bulk invalidation—it’s slower and less scalable.
“Varnish’s power isn’t in its speed—it’s in its programmability. You’re not configuring a cache; you’re writing HTTP policy. That shifts responsibility from ops to platform engineering—and raises the bar for correctness.” — Per Buer, Creator of Varnish Cache and CTO at Varnish Software (2010–2018)
Frequently Asked Questions
Does Varnish support HTTPS termination?
No—and intentionally so. Varnish operates at layer 7 (HTTP), not layer 4 (TLS). Terminating SSL/TLS upstream (with HAProxy, NGINX, or a cloud load balancer) is the recommended, secure pattern. Attempting TLS in Varnish would compromise performance, increase attack surface, and violate its architectural focus. Modern deployments use NGINX or Envoy for TLS termination, then forward HTTP/1.1 or HTTP/2 cleartext to Varnish.
Can Varnish cache POST requests?
By default, no—RFC 7231 prohibits caching POST responses unless explicitly marked with Cache-Control: public and Content-Location. However, VCL can override this: if (req.method == \"POST\" && req.url ~ \"^/api/search\") { return(hash); }. Use with extreme caution: ensure idempotency, avoid caching responses containing session tokens or PII, and always validate with end-to-end tests.
How much RAM does Varnish need?
There’s no fixed formula—but empirical data shows optimal allocation is 60–75% of available RAM, reserved exclusively for Varnish’s storage. For a 16 GB server, allocate 10–12 GB to Varnish. Monitor MAIN.sma.Transient.g_alloc and MAIN.sma.Transient.g_bytes in varnishstat: if g_alloc grows rapidly while g_bytes stays flat, objects are being allocated but not stored—indicating TTLs are too short or cache keys are overly granular.
Why “Just Use a CDN” Isn’t Enough
CDNs excel at global asset distribution and DDoS mitigation—but they introduce unavoidable latency (minimum 20–50 ms round-trip to edge) and operate outside your control plane. You cannot run custom VCL on Cloudflare Workers or Fastly Compute@Edge without vendor lock-in and pricing tiers that scale with compute time, not request volume. More critically, CDNs often ignore subtle Vary headers or mishandle Cookie-driven personalization, leading to cache pollution and incorrect content delivery.
Varnish solves the *origin-facing* bottleneck—the part CDNs cannot reach. It reduces origin load before traffic even leaves your data center, enabling smaller, cheaper infrastructure. One fintech client reduced AWS EC2 spend by 40% after adding Varnish in front of their API gateway, not because Varnish was “faster,” but because it eliminated redundant database queries for identical dashboard requests from authenticated users.
Conclusion: Move Beyond Caching—Engineer HTTP Behavior
Varnish is not middleware you “install and forget.” It’s an HTTP policy engine demanding deliberate design: understanding cache lifetimes, mastering Vary semantics, auditing origin headers, and treating cache invalidation as a first-class deployment concern. Yet the payoff is tangible—measured in milliseconds saved, servers decommissioned, and uptime preserved during traffic surges. If your site serves dynamic content at scale, if origin latency frustrates your team, or if cache hit ratios plateau below 80%, Varnish offers a proven, open-source path forward—not as a bandage, but as infrastructure-grade HTTP intelligence.
varnishstat -1 | grep \"cache_hit\\|cache_miss\" over 5 minutes of synthetic traffic. Share your results—or your toughest caching challenge—in the comments below.










