
Magento full page cache stores rendered pages so repeat requests skip PHP entirely, and Varnish makes that cache serve from memory at the edge. On a Hyva theme the whole page is cached, while personalized pieces like the mini-cart and customer greeting load separately. Hyva favors Magento’s private content system, loading those pieces client-side after the cached page renders, over the older ESI hole-punching approach, though both are available. Tag-based invalidation keeps the cache correct when data changes.
Full page cache is the single biggest reason a Magento store feels fast, and getting it right on Hyva means understanding what gets cached, how the dynamic pieces are handled, and how the cache is cleared when a price or stock level changes. This guide covers the configuration, the hole-punching mechanics, and the Hyva-specific choices that keep pages both fast and correct.
What full page cache does, and why Varnish
Magento full page cache stores the fully rendered HTML of a page so that the next shopper who requests it gets the stored copy instead of Magento rebuilding it from scratch. Rebuilding a category page touches the database, runs layout, and renders blocks; serving from cache skips all of that.
Magento supports two cache backends. The built-in cache uses your cache storage, Redis or Valkey, and is simple but runs through PHP. Varnish is a dedicated HTTP cache that sits in front of Magento and serves cached pages from memory without touching PHP at all, which is dramatically faster under load. For any production store with real traffic, Varnish is the standard choice.
| Aspect | Built-in FPC | Varnish |
|---|---|---|
| Where it runs | Through PHP, backed by Redis/Valkey | Dedicated HTTP cache in front of Magento |
| Speed under load | Good | Much faster, serves from memory |
| Setup complexity | Minimal | Requires Varnish configuration |
| Dynamic content | Private content or placeholders | ESI or private content |
| Recommended for | Development, tiny stores | Any production store with traffic |
Configuring full page cache
The core configuration lives in the Magento Admin under Stores, Configuration, Advanced, System, in the Full Page Cache section. There you select the caching application, built-in or Varnish, and set the public content TTL, which defaults to 86400 seconds, or 24 hours. That TTL controls how long a cached page stays valid before it is refreshed, independent of tag-based invalidation.
For Varnish, Magento generates a VCL configuration file you load into your Varnish instance. Getting the VCL right, and confirming Varnish is actually caching rather than passing every request through, is where many stores lose the benefit. A store that “has Varnish” but shows a low cache-hit ratio is usually misconfigured, and the fix is verifying the VCL and the cache headers Magento sends. This kind of verification is standard in any serious Magento development performance engagement.
The problem full page cache has to solve
Here is the tension at the heart of full page caching. You want to cache a category or product page once and serve it to everyone, but parts of that page are different for each shopper: the mini-cart shows their items, the header greets them by name, recently viewed products are personal. If you cache the whole page including those parts, every shopper sees the first shopper’s cart, which is both wrong and a privacy problem.
There are two ways to solve this, and Hyva makes a deliberate choice between them.
ESI hole-punching versus private content
The two approaches to personalized blocks on cached pages:
- ESI hole-punching. Edge Side Includes let Varnish cache the page shell while marking specific blocks as non-cacheable. Varnish serves the cached shell instantly, then fetches the punched-out blocks, the mini-cart, cart totals, customer greeting, from Magento separately and injects them. The page is cached; the holes are filled per request.
- Private content. Magento’s private content system caches the entire page, including placeholder markup for personalized blocks, and loads the actual personalized data client-side via a separate request after the page renders in the browser. Nothing personal is ever stored in the shared cache.
Hyva favors the private content approach. Because Hyva already fetches interactive data client-side over GraphQL and customer sections, loading personalized blocks after the cached page renders fits its architecture naturally, and it keeps the cached HTML fully public and shareable. ESI remains available and is genuinely useful for some server-rendered personalized blocks, but the Hyva default leans on client-side private content rather than server-side hole-punching. The practical upshot: on a well-built Hyva storefront, the page shell is aggressively cached and the personal pieces hydrate in the browser.
Cache invalidation: keeping cached pages correct
A fast cache that serves stale prices is worse than no cache. Magento solves this with cache tags. Every cached page carries an X-Magento-Tags header listing the entities it depends on, products, categories, CMS blocks. When one of those entities changes, Magento issues a tag-based PURGE to Varnish, which invalidates every cached page carrying that tag.
Two things are worth knowing. First, ESI fragments are stored in Varnish alongside full page responses and use the same tag mechanism, so a tag PURGE invalidates both. Second, invalidation is targeted: changing one product purges the pages that reference it, not the entire cache, so the rest of the site stays warm. This is what lets a busy store update inventory constantly without collapsing its cache-hit ratio.
The common failure is over-broad invalidation, a poorly built extension or customization that flushes far more of the cache than it needs to on every save, which quietly destroys performance because pages are constantly rebuilding. Auditing what triggers invalidation is a high-value exercise on a slow store.
Tuning for a high cache-hit ratio
The metric that matters is the cache-hit ratio: the share of requests served from cache rather than rebuilt. The levers that raise it:
- Confirm Varnish is caching. Verify the VCL and that Magento sends cacheable headers on public pages.
- Keep personalized data out of the cached HTML. Use private content or ESI for anything shopper-specific so the page shell stays public.
- Avoid cache-busting query parameters. Tracking parameters that vary per visit can split the cache; normalize or strip them in the VCL.
- Watch invalidation. Ensure saves invalidate narrowly, not site-wide.
- Set a sensible TTL. The 24-hour default is fine for most public content; tag invalidation handles freshness within that window.
Measure the cache-hit ratio before and after each change so you know it helped.
Warming the cache and handling the cold-start problem
A cached page is only fast once it has been cached. The first shopper to hit an uncached page pays the full rebuild cost, and after a deploy or a full cache flush, every page is uncached. On a busy store that cold-start moment can spike server load and slow the first wave of shoppers.
Two practices soften this. A cache warmer crawls your important pages, homepage, top categories, best-selling products, right after a deploy so they are cached before real traffic arrives. And avoiding unnecessary full flushes matters: a full cache clear on every deploy throws away a warm cache you could have kept. Where possible, rely on targeted tag invalidation rather than flushing everything, so most of the cache survives a routine change.
For scheduled content changes, warm the affected pages ahead of the traffic they will draw. A homepage refresh for a sale is worth warming before the campaign email goes out, not after shoppers start arriving to an uncached page.
Where a CDN fits alongside Varnish
Varnish caches at your origin; a CDN caches closer to the shopper. The two are complementary. A CDN in front of Varnish serves static assets, images, CSS, and JavaScript, from edge locations near the user, cutting latency on the heavy parts of the page, while Varnish handles the cacheable HTML at the origin. On a Hyva store, where the theme is already light on JavaScript, a CDN mostly accelerates images and the initial HTML delivery.
The key is coordinating cache invalidation across both layers, so a product change purges Varnish and, where relevant, the CDN. Getting that coordination right prevents the frustrating case where Varnish serves a fresh page but the CDN still holds an old asset.
Frequently asked questions
Does Hyva use ESI or private content for personalized blocks?
Hyva favors Magento’s private content system, loading personalized blocks like the mini-cart client-side after the cached page renders. This fits Hyva’s client-side data-fetching architecture and keeps the cached HTML fully public. ESI hole-punching remains available and is useful for some server-rendered personalized blocks.
What is hole-punching in Magento full page cache?
Hole-punching is the technique of caching a page while treating specific blocks as dynamic. With ESI, Varnish caches the page shell and fetches the punched-out blocks separately per request. With private content, the personalized blocks load client-side after the cached page renders. Both let a mostly-cacheable page carry personal data.
Why is my Varnish cache-hit ratio low?
Usually a misconfiguration: the VCL is not caching, Magento is sending non-cacheable headers on public pages, personalized data is polluting the cached HTML, or query parameters are splitting the cache. Verify the VCL, keep personal data in private content, and normalize tracking parameters.
How does Magento clear the cache when a product changes?
Through cache tags. Each cached page carries an X-Magento-Tags header listing the entities it depends on. When a product changes, Magento sends a tag-based PURGE to Varnish, which invalidates only the pages referencing that product, leaving the rest of the cache warm.
What TTL should I set for full page cache?
The default public content TTL is 86400 seconds, or 24 hours, which suits most stores. Tag-based invalidation refreshes pages when their underlying data changes within that window, so the TTL is a backstop rather than the primary freshness mechanism.
Where this fits
Full page cache on Hyva is a layered system: Varnish serves the public page shell from memory, private content loads the personal pieces client-side, and tag-based invalidation keeps everything correct when data changes. Get the VCL right, keep personalized data out of the cached HTML, and audit invalidation, and your cache-hit ratio, and your storefront speed, stay high.
Bemeir is the first US-based Hyva partner and a full Adobe Commerce agency, with a deep technology partner ecosystem across hosting, caching, and CDN tooling. We configure Varnish, private content, and cache invalidation on Hyva and Magento builds, and we also work across Shopify, Shopware, and BigCommerce. Read more about Bemeir and how we tune Magento performance.
External references: the Hyva caching documentation, a guide to Magento full page cache and Varnish setup, and a practical piece on optimizing Magento with Hyva and Varnish.





