Performance

Magento Cache Health: Configuration and Hit Rates

An enabled cache is not a working cache. Confirm Varnish and Redis configuration, then measure the hit rate that config never shows and the reasons it drops.

Jason Schuman · May 6, 2026

An enabled cache is not the same as a working cache

Every Magento store has caching turned on. Far fewer have caching that is actually doing its job, and the difference does not show up in a status command.

A cache can be enabled, correctly configured on paper, and still serve a low hit rate that leaves most requests hitting the origin at full cost.

This article covers how to confirm the cache configuration, how to measure the hit rate that config never shows you, and the two most common reasons that rate is lower than it should be.

What the stack should look like

A healthy Magento cache stack has a few distinct layers, and each has a job:

  • Full-page cache, served by Varnish in front of the application on any store of size.
  • The default cache and block, layout, and config caches, backed by Redis or Valkey rather than the filesystem.
  • Sessions in Redis, kept out of both the database and the local disk.

When those layers are split correctly, the application does the least possible work per request. When they are collapsed onto the filesystem or misconfigured, the store pays for cache it is not really getting.

Confirm the configuration first

Start with what the store thinks it is doing. bin/magento cache:status shows which cache types are enabled, and all of them should be on in production.

Check which full-page cache backend is active with bin/magento config:show system/full_page_cache/caching_application. A value of 1 is the built-in PHP cache, and 2 is Varnish. A production store of any size returning 1 is leaving performance on the table.

Then confirm Redis is actually backing the caches in app/etc/env.php, with the default cache, page cache, and sessions on separate Redis databases rather than sharing one. Sharing a database is a common misconfiguration that makes a targeted cache flush clear more than it should.

Measure the hit rate

Configuration tells you the cache exists. The hit rate tells you whether it works, and you have to measure it directly.

For Varnish, varnishstat reports cache_hit against cache_miss in real time. For Redis, redis-cli info stats exposes keyspace_hits and keyspace_misses, and the ratio between them is the number that matters.

A full-page cache running at a 40% hit rate is doing less than half its job. The other 60% of requests are hitting your origin at full cost, no matter what the config says.

Why full-page cache hit rate drops

A low full-page cache hit rate usually traces to blocks that opt out of caching. A single block marked cacheable="false" in layout XML makes the entire page uncacheable, and one careless extension can do that to your most-visited templates.

Short time-to-live settings and overuse of customer-specific sections also pull the rate down. Every page that varies per customer is a page Varnish cannot serve from cache.

Finding these means auditing layout XML for cacheable="false" and reviewing which blocks were pushed into private, per-customer sections that did not need to be.

Redis eviction, the silent cache killer

The other common cause is a Redis instance that is too small for what the store asks it to hold. When Redis hits its maxmemory limit, it starts evicting keys to make room, and evicted cache is a guaranteed future miss.

Check evicted_keys in redis-cli info stats. A number that climbs steadily means the cache is thrashing, filling and evicting faster than it can serve, which shows up as a low hit rate no amount of config review would explain.

The fix is either more memory for Redis or a sane maxmemory-policy, but you only know to look once the eviction count tells you the cache never had room to work.

Do not forget OPcache

The caches Magento manages are not the only ones that matter. PHP's OPcache stores compiled bytecode, and on a codebase as large as Magento it has a real effect on response time.

Confirm OPcache is enabled and sized for the code, because a Magento install can outgrow a default configuration. When opcache.memory_consumption is too small, PHP evicts compiled code and recompiles it constantly, which is wasted work on every request.

OPcache sits outside bin/magento cache:status entirely, which is exactly why it gets missed in a cache review that only looks at what Magento reports about itself.

Health, not just presence

Cache health is a measurement question, not a checkbox. Enabled caches with a poor hit rate cost you the same origin load as no cache at all, while looking correct in every status output.

Knowing your real hit rates, and what is dragging them down, turns cache from an assumption into a number you can improve. That measurement is where a serious performance review starts, ahead of any deeper origin work.