Magento 2 Cache Tag Strategy: Prevent Cache Invalidation Storms
Magento 2's full page cache is one of its strongest performance features — when it works. But every week, we see stores where a simple product save triggers a 30-second Varnish flush and subsequent cache stampede. The culprit is almost never Varnish itself. It's cache tags. This post covers how Magento 2 cache tags work, why broad tags destroy performance, and exactly how to audit and fix them. How Cache Tags Work in Magento 2 Every cached page, block, and data fragment in Magento is tagged with identifiers. When a product changes, Magento invalidates all cache entries tagged with that product's ID. The tag system is hierarchical: cat_p_123 — specific product cat_p — all products cat_c_5 — specific category cat_c — all categories cms_b_about_us — a CMS block cms_p — all CMS pages These tags are stored alongside cached content and used during invalidation. When you call $cache->clean(["cat_p_123"]) , every cache entry tagged with cat_p_123 is removed. This is elegant until someone tags a global block with cat_p , and saving any product flushes half your store. The Invalidation Storm Problem Here's what happens during a storm: Admin saves a simple product update (price change) Magento generates the invalidation list: cat_p_456 , cat_c (because the product is in categories), cat_p (from a badly written block) cat_p is too broad — it matches the product list page, layered navigation, homepage widgets, and every product detail page Varnish receives 50,000 BAN requests Store goes from sub-100ms response times to 2-5 seconds for the next 10 minutes while the cache rebuilds We've seen this on a store with 80,000 SKUs. A single product save dropped cache hit rate from 94% to 12%. Diagnosing Bad Cache Tags Check Your Current Tags Add this to any block template to inspect what tags are being applied: $block -> getCacheKeyInfo (); // Or for the full page: $block -> getIdentities (); For a full audit, intercept cache writes in development: // In di.xml: < type name = "Magento\Fr