Cache performance monitoring for Redis and Memcached gets treated as an afterthought on a lot of teams, right up until the moment a cache node falls over and the database behind it gets hit with ten times its normal query load. Monitoring Redis and Memcached properly means watching a different set of signals than you’d track on a regular application server, and this article covers exactly which metrics matter, how to alert on them without drowning in noise, and what a real cache-related incident tends to look like from the inside.
The Myth That Cache Failures Just Mean “Slower”
The common assumption is that if Redis or Memcached goes down or gets slow, the app just gets a bit sluggish while it falls back to the database. That’s not what usually happens.
In practice, a cache outage or a sudden drop in hit rate sends a wave of traffic straight to the database that it was never sized to handle directly. Connection pools exhaust, query queues back up, and what looked like a caching layer problem turns into a full outage within minutes. Cache monitoring isn’t optional polish on top of database monitoring – it’s a load-shedding mechanism, and when it fails silently, everything downstream inherits the blast radius.
Redis Metrics That Actually Predict Trouble
Redis exposes most of what you need through the INFO command, but a handful of fields matter far more than the rest:
used_memory vs maxmemory – Redis doesn’t gracefully slow down as it approaches its memory ceiling. Depending on the configured eviction policy, it either starts evicting keys aggressively or, if maxmemory-policy is set to noeviction, starts rejecting writes outright. Track this as a percentage and alert well before 100%, not at it.
evicted_keys – A rising eviction counter means your working set no longer fits in memory. A few evictions on a cache that’s supposed to be a cache is normal. A steep upward trend usually means someone shipped a feature that caches far more data than expected, or the instance was sized for last year’s traffic.
keyspace_hits vs keyspace_misses – The ratio between these gives you hit rate. A cache running below 80-90% hit rate (the acceptable number varies a lot by use case) is often not doing its job, and it’s worth asking whether TTLs are too short or the key strategy is wrong before assuming you just need a bigger instance.
connected_clients and blocked_clients – A steady climb in connected clients without a corresponding traffic increase is a classic sign of a connection leak in application code, not a Redis problem at all.
rdb_last_save_time and replication lag (master_repl_offset on primary vs replica) – If you’re running Redis for anything other than pure ephemeral caching, replication lag creeping up is an early warning that a failover would lose data.
Memcached Metrics That Deserve the Same Attention
Memcached’s stats output is simpler than Redis’s, but it’s just as easy to ignore until something breaks:
evictions – Same story as Redis: this is the single clearest signal that allocated memory doesn’t match actual demand.
get_hits / get_misses – Watch this ratio over time rather than as a single snapshot. A slow decline over weeks is a capacity issue creeping up; a sudden cliff usually means a deploy changed cache key naming or a flush happened.
curr_connections – Memcached has a hard connection limit, and hitting it doesn’t degrade gracefully – new connections just get refused. This is worth watching alongside application-side connection pooling, similar to how you’d approach database connection pool monitoring on the database itself.
bytes vs limit_maxbytes – Memcached’s slab allocator means memory can look “full” from the OS’s perspective while individual slab classes still have room, or vice versa. Don’t rely on total memory usage alone – check slab-level stats if evictions look off relative to overall usage.
A Realistic Incident Timeline
A mid-sized e-commerce backend running Redis as a session and product-catalog cache is a good example of how this plays out. Traffic grows steadily over a few months, but the Redis instance’s maxmemory setting never gets revisited. Hit rate holds around 92% for weeks, then starts sliding.
Day 1, hit rate drops to 85% – barely noticeable in dashboards, no alert fires because the threshold was set at 80%. Day 4, hit rate hits 78%, evictions spike, and database CPU starts running 20% hotter than baseline during peak hours. Day 6, a flash sale doubles traffic, the cache can’t absorb the extra load, evictions go vertical, and the database connection pool saturates within 12 minutes. The site effectively goes down for checkout, not because Redis crashed, but because it quietly stopped doing its job days earlier.
The fix afterward wasn’t a bigger Redis instance alone – it was setting an eviction-rate alert and a hit-rate trend alert that would have caught the slide on day 2 instead of day 6.
Alerting on Cache Metrics Without the Noise
Static thresholds on eviction counts or connection counts tend to either fire constantly on normal cache churn or stay silent until it’s too late. Trend-based and rate-of-change alerts work much better for cache layers specifically because normal operation already involves some background eviction and connection cycling.
The same principles covered in reducing alert fatigue with smarter thresholds and notification rules apply directly here: alert on hit rate dropping below its own rolling baseline rather than an arbitrary fixed number, and separate “needs attention this week” from “wake someone up now.”
Why Baselines Matter More for Caches Than Most Components
Cache workloads vary enormously between applications – a session store, a query-result cache, and a rate-limiting counter store all have completely different normal patterns for memory growth, hit rate, and connection counts. A generic “hit rate below 90% is bad” rule breaks down fast once you have several caches serving different purposes.
This is exactly the kind of situation where knowing your own normal matters more than industry benchmarks, as covered in performance baselines and knowing your normal to spot anomalies. Two weeks of clean baseline data on each cache instance will catch far more real problems than a one-size-fits-all threshold ever will.
FAQ
Is a low hit rate always a problem?
Not automatically. Some caches are intentionally used for a narrow set of hot keys and will show lower overall hit rates by design. What matters is whether the hit rate is stable relative to its own historical baseline, not whether it hits some universal percentage.
Should Redis and Memcached be monitored differently from application servers?
Yes. CPU and disk usage matter far less for these than memory pressure, eviction rate, and connection counts. A Redis or Memcached instance can look completely healthy on standard server metrics while quietly failing its actual job.
How often do eviction and hit-rate metrics need to be checked?
Continuously, not periodically. These values can shift meaningfully within minutes during traffic spikes, which is exactly when the consequences of missing the shift are most expensive.
Summary
Redis and Memcached don’t fail loudly – they degrade quietly through rising evictions and falling hit rates, and the database behind them absorbs the consequences. Tracking memory usage against configured limits, eviction trends, hit rate relative to its own baseline, and connection counts covers the vast majority of real incidents before they become outages. The practical takeaway: set trend-based alerts on eviction rate and hit rate today, not fixed thresholds picked from a generic guide, and revisit them every time traffic patterns shift meaningfully.
