A cache is only fast until something keeps clearing it
A well-configured Magento cache can still deliver poor performance if something is constantly invalidating it. A cache that gets wiped every few minutes is barely a cache at all.
These invalidation storms are usually not obvious. The cache is enabled, the hit rate looks fine on average, and yet the store has periodic slowdowns that line up with imports, price updates, or a particular extension doing its work.
This article covers how Magento invalidation works, what turns normal invalidation into a storm, how Redis and the full-page cache amplify it, and how to find and calm the source.
How Magento cache invalidation works
Magento caches are tag-based. Every cached block and page is stored with the identities of the entities it depends on, so a product page carries that product's cache tag.
When an entity is saved, Magento invalidates every cache entry tagged with its identity. Saving one product clears the cached pages that reference it, which is exactly the behavior you want for correctness.
The system works well when saves are occasional and targeted. It turns into a problem when something saves many entities at once, or invalidates far broader than the change actually requires.
What a storm actually is
An invalidation storm is a burst of cache clearing large enough to hurt performance. Instead of a few pages being invalidated, a large fraction of the cache is cleared in a short window.
The storefront then has to rebuild all of it from the origin, which is slow and expensive. If the burst repeats on a schedule, the store never gets to enjoy a warm cache for long.
Full flush versus targeted clean
Magento has two very different cache operations, and confusing them causes storms. A clean removes only the entries with specific Magento tags, while a flush wipes the entire cache storage.
On the command line these are cache:clean and cache:flush, and the difference matters enormously. A flush clears everything, including entries other applications may share in the same backend, and forces a complete cold rebuild.
The problem appears when code calls the equivalent of a full flush for a change that a targeted clean would have covered. One product save that triggers a full flush is a self-inflicted storm.
Mass entity saves as the trigger
The most common storm source is a process that saves many entities in a loop. Product imports, bulk price updates, and inventory syncs all do this.
Each save invalidates its own cache tags, and thousands of saves in quick succession invalidate thousands of cache entries. Even with correct, targeted invalidation, the sheer volume clears a large part of the cache at once.
This is why store performance often dips during imports and overnight price rule runs. The work itself is legitimate, but its invalidation footprint hits the cache like a flush spread over a few minutes.
The full-page cache and Varnish bans
The full-page cache feels storms most, because it holds the rendered pages customers actually receive. With Varnish, invalidation happens through bans or purges keyed on cache tags.
A broad tag invalidation tells Varnish to ban a large set of cached pages. Varnish then has to fetch fresh copies from the origin for every banned page as traffic requests them.
When a mass save bans a wide swath of pages, the origin suddenly serves full-cost responses for pages that were previously instant. That spike in origin work is the visible symptom of the storm.
Redis and the cost of broad invalidation
Magento stores cache tags in Redis as sets that map tags to the cache entries carrying them. Invalidating a tag means looking up that set and removing every entry in it.
A broad invalidation touches many tags and many entries, which is real work for Redis. During a storm, Redis CPU can spike as it processes a flood of tag invalidations, and that latency feeds back into every request waiting on the cache.
Storms show up as Redis and origin spikes that line up with a scheduled job, not with customer traffic.
The cache miss stampede that follows
After a broad invalidation, the danger is not just the empty cache but the rush to refill it. When many requests hit the same newly-invalid pages at once, they all miss the cache and all try to rebuild from the origin simultaneously.
This is a cache stampede, and it can overwhelm the origin far more than steady traffic would. The origin does redundant work building the same pages for concurrent requests, right when it is already busy.
A storm followed by a stampede is how a background import turns into customer-facing slowness. The invalidation empties the cache, and the stampede piles onto the origin trying to fill it back up.
Extensions that over-invalidate
Some extensions invalidate more aggressively than they need to. An extension that flushes the full cache when it changes one setting, or clears broad tags on a narrow change, creates storms out of small actions.
This is often a shortcut in the extension's code: flushing everything is easier than working out the precise tags to clear. It works correctly, in that stale content is avoided, but it pays for that correctness with a storm.
When performance dips correlate with a specific extension's activity, its invalidation behavior is worth reading. The fix is often getting the vendor to narrow what it invalidates, or isolating when it runs.
Reindex-triggered invalidation
Indexing and cache invalidation are linked through the materialized view system. When indexers run on schedule, they process changelog tables of what changed and invalidate the corresponding cache.
A large batch of catalog changes produces a large changelog, and processing it invalidates a correspondingly large set of cache entries. This is why a big catalog update and the reindex that follows can produce a storm even without an explicit flush.
Keeping indexers on schedule, and keeping the batches of change reasonable, limits how much any single reindex invalidates at once.
Config changes that flush everything
Some administrative actions invalidate far more than they appear to. Saving certain configuration, or an extension that clears the full cache when any of its settings change, can trigger a broad flush from a single click.
This is easy to miss because it feels like a small change. An admin saves a setting, and behind it the store dumps a large part of its cache and begins rebuilding from cold.
On a busy store, an innocent-looking config save at peak time can start a storm. Knowing which actions flush broadly lets you time them, or fix the code that over-reacts to them.
The warm-up problem after a flush
An empty cache is slow until it is warm again, and warming takes real traffic or a deliberate crawl. Right after a flush, every page is a miss, and the origin serves full-cost responses until the cache refills.
This is why the minutes after a deploy or a flush are the slowest for customers. The cache is doing no work yet, and the origin is doing all of it.
Some teams warm the cache deliberately with a crawler after a flush, fetching key pages so the first real customers hit a warm cache. Without that, the warm-up cost lands on whoever happens to browse first.
Shared cache backends multiply the blast
When multiple application instances or environments share one Redis backend, a flush from one can affect all of them. This is where cache:flush is especially dangerous, because it wipes the entire storage, not just one store's tagged entries.
cache:flush against a shared Redis backend can cold-start every store that shares it, not just the one you ran it on. Targeted cache:clean exists precisely to avoid that blast radius.The safer setup gives each instance its own cache database, so invalidation stays contained. Where a backend is genuinely shared, the discipline of using clean over flush matters even more.
Tag granularity decides the blast radius
How narrowly the cache can be invalidated depends on how its tags were designed. Blocks declare their cache identities, and those identities become the tags Magento invalidates against.
Coarse tags mean a small change invalidates a large set, because everything shares the same broad tag. Fine-grained identities let Magento clear exactly the affected entries and leave the rest warm.
When custom blocks or extensions use overly broad identities, they make targeted invalidation impossible. Reviewing tag design is part of why some stores can invalidate surgically while others clear half the cache for one change.
Tag granularity decides how much the cache clears for a single change.
Diagnosing a storm
The signature of a storm is correlation. Performance dips that line up with a schedule, rather than with traffic, point at a background process rather than customer load.
Watch the full-page cache hit rate, Redis CPU, and origin response time together over a day. Storms appear as synchronized spikes at the times imports, price rules, or specific extensions run, with the hit rate dropping right after.
Correlating those spikes with the cron schedule and import logs usually identifies the exact job responsible. Once you can name the job, you can decide how to calm it.
Redis itself can help you measure. Its statistics show keyspace activity and evictions, and watching them during a suspected storm confirms whether a burst of invalidation is really happening at that time. That measurement turns a hunch about "the store feels slow during imports" into evidence about what the cache is actually doing.
Deploy-time flushing is expected, but plan for it
Deploys flush the cache by design, because new code and templates must not serve stale cached output. This is correct behavior, and it still leaves the store cold immediately after every release.
The way to handle it is timing and warming, not avoidance. Deploying during low traffic, and warming key pages afterward, keeps the unavoidable post-deploy flush from landing on a full house of customers.
Frequent deploys during peak hours turn a normal flush into a recurring storm. Batching releases and timing them well is part of keeping the cache useful.
Asynchronous invalidation through the queue
Some invalidation flows through the message queue rather than happening inline. Bulk actions and certain operations enqueue work whose consumers then invalidate cache as they process.
This can spread a storm out over time, which is better, or it can pile up if the consumers process a large backlog all at once. A queue that suddenly drains a big batch can invalidate broadly in a short window, producing the same storm from a different direction.
Watching consumer activity alongside cache metrics catches this. A spike in invalidation that lines up with a consumer draining its queue points at asynchronous invalidation rather than a direct save loop.
Heavy content tools add cache identities
Content tools like Page Builder store rich content that carries its own cache dependencies. Complex content blocks can reference many entities, and each reference is a cache identity that can be invalidated.
A page assembled from many dynamic blocks has a broad set of cache tags, so changes ripple more widely than a simple page would. Extensions that add dynamic content components do the same, expanding what a given change invalidates.
This is not a reason to avoid rich content, but it is a reason to understand its cache footprint. Content that pulls in many entities invalidates against all of them, which is worth knowing when a content-heavy store shows storm behavior.
The cost lands as origin capacity
Every storm ultimately spends origin capacity. Pages that would have been served from cache instead run the full application stack, and that consumes PHP workers, database connections, and CPU.
This is why invalidation storms and capacity problems are connected. The cache exists to keep origin load manageable, and a store that keeps clearing it forces the origin to do work it was sized to avoid.
Calming the source
The fixes follow directly from the causes. The goal is to invalidate less, and to invalidate at better times.
- Batch and schedule heavy operations for off-peak hours, so the storm and the stampede land when traffic is low.
- Prefer targeted
cache:cleanover fullcache:flushin any code you control. - Get over-invalidating extensions to narrow their tags, or isolate when they run.
- Keep indexers on schedule and change batches reasonable, so no single reindex invalidates a huge set at once.
None of these disables invalidation, which is necessary for correctness. They shrink its footprint and move it away from peak traffic, which is what turns a storm back into ordinary housekeeping.
Varnish grace mode softens the blow
Varnish has a feature that reduces the damage of a storm without addressing its cause. Grace mode lets Varnish serve slightly stale content while it fetches a fresh copy in the background.
With grace enabled, a customer requesting a just-invalidated page gets the stale version immediately, and Varnish refreshes it behind the scenes. That prevents the cache miss stampede, where every request waits on the origin at once.
Grace is a safety net, not a fix. It keeps a storm from becoming an outage, but the underlying over-invalidation is still worth calming, because stale content and constant background refetching have costs of their own.
A cache that stays warm
An invalidation storm is a cache doing its job too broadly, too often, at the wrong time. The result looks like a caching problem but is really a workload and configuration problem behind the cache.
The fix is rarely dramatic once the source is named. It is usually a matter of moving a job off-peak, narrowing what an extension clears, or replacing a full flush with a targeted clean, each a small change with a large effect on how warm the cache stays.
Knowing what invalidates your cache, how broadly, and on what schedule turns mysterious periodic slowdowns into a named, fixable cause. Finding those storms is a standard part of a serious performance review.