Final StretchOrdered learning track

Cache Operability: Eviction, Memory Pressure, Stampede, Hot Key, Failover

Learn AWS Application and Database - Part 086

Cache operability untuk ElastiCache/Redis/Valkey: eviction, memory pressure, stampede, hot key, failover, connection storm, observability, runbook, dan production readiness.

8 min read1576 words
PrevNext
Lesson 8696 lesson track80–96 Final Stretch
#aws#elasticache#redis#valkey+5 more

Part 086 — Cache Operability: Eviction, Memory Pressure, Stampede, Hot Key, Failover

Core idea: cache biasanya ditambahkan untuk membuat sistem lebih cepat. Di production, cache sering menjadi komponen yang membuat sistem lebih rapuh jika operability-nya lemah. Cache yang sehat menurunkan latency. Cache yang sakit menciptakan database storm, stale data, connection exhaustion, dan incident yang sulit dibedakan dari database problem.


1. Tujuan Pembelajaran

Setelah bagian ini, kamu harus bisa:

  1. Membaca sinyal kesehatan ElastiCache/Redis/Valkey dari metric utama.
  2. Membedakan eviction normal, memory pressure, fragmentation, hot key, stampede, dan connection storm.
  3. Mendesain alarm yang actionable, bukan noise.
  4. Membuat runbook untuk cache hit-rate collapse, failover, eviction spike, dan stale data incident.
  5. Mendesain client behavior yang aman saat cluster failover, timeout, dan slot topology berubah.
  6. Menentukan apakah cache outage harus fail-open, fail-closed, atau degraded.

2. Operability Mental Model

Cache berada di jalur panas.

Ketika cache bermasalah, efeknya tidak berhenti di cache.

cache latency naik -> app thread menunggu -> connection pool penuh
cache miss naik    -> database QPS naik -> DB latency naik
cache failover     -> client reconnect storm -> CPU/network spike
cache eviction     -> hit rate turun -> source of truth dihantam
hot key            -> satu shard/node bottleneck meskipun cluster besar

Rule:

A cache incident is often a database incident in disguise.

3. Critical Metrics

AWS merekomendasikan alarm untuk metrik seperti CPU, engine CPU, swap, evictions, connections, memory, network latency, replication, dan traffic management pada ElastiCache.

MetricBaca sebagaiRisiko
CPUUtilizationhost CPUnode overload, network/I/O pressure
EngineCPUUtilizationRedis/Valkey engine CPUcommand hot path, single-thread pressure
DatabaseMemoryUsagePercentage / memory metricsmemory pressureeviction, OOM, latency
Evictionskey dibuang karena memory pressurehit rate drop, DB storm
CurrConnectionsactive client connectionsconnection leak/storm
NewConnectionschurn/reconnectfailover, bad pooling
CacheHitRatecache effectivenessmiss storm, invalidation issue
ReplicationLagreplica behind primarystale read/failover risk
NetworkBytesIn/Outtraffic volumehot key, large values
BytesUsedForCacheused memorycapacity trend
SwapUsagehost memory stresssevere performance risk

Important distinction:

CPUUtilization high      -> host is busy.
EngineCPUUtilization high -> Redis/Valkey command execution is the bottleneck.

For Redis-like engines, one hot command pattern can saturate engine CPU even when cluster aggregate capacity looks fine.


4. Dashboard Layout

Minimum dashboard:

1. User-facing latency/error
2. Cache latency and command error
3. Hit rate / miss rate
4. Evictions and memory usage
5. Engine CPU and host CPU
6. Connections and new connections
7. Network throughput
8. Replication lag / failover events
9. DB QPS and DB latency
10. Top tenant/key family approximation from app telemetry

Dashboard must show cache and database together. Otherwise you will misdiagnose cache miss storm as “database suddenly slow”.


5. Eviction

Eviction means cache has reached memory pressure and removes keys according to maxmemory-policy.

Common policies:

PolicyMeaningUse carefully when
noevictionreject writes when fullcache is not allowed to silently drop keys
allkeys-lruevict least-recently-used among all keysgeneral cache-aside
volatile-lruevict LRU only among keys with TTLnot all keys have TTL
allkeys-lfuevict least-frequently-usedskewed workloads
volatile-ttlevict keys near expiryTTL-heavy cache

If cache is purely derived state, eviction can be acceptable. If cache stores coordination/session state, eviction may log users out or break control behavior.

Cache data can be evicted.
Coordination state should be protected or moved to durable store.

6. Memory Pressure

Memory pressure sources:

SourceSymptomFix
Too many keysmemory trend growsTTL, namespace cleanup, capacity scale
Large valuesnetwork + memory highcompress, split, avoid giant blobs
No TTLcache never drainsenforce TTL policy
Stampede fillsudden memory jumprequest coalescing, admission control
Fragmentationmemory used strange vs datasetmonitor, restart/scale if needed
Hot ephemeral keyschurn highkey design, batching

Key question:

Is memory growth proportional to business growth, traffic spike, deployment bug, or missing TTL?

Run this investigation:

1. Did deployment change key schema or TTL?
2. Did hit rate fall before memory rose?
3. Did evictions start after a traffic event?
4. Is memory concentrated in one shard/node?
5. Did value size change?
6. Did background warming/backfill run?

7. Cache Stampede

Cache stampede happens when many requests miss the same key and all rebuild it concurrently.

Mitigations:

PatternHow it worksTrade-off
TTL jitterrandomize expirysimple, approximate
Request coalescingonly one request rebuildsneeds local/distributed coordination
Stale-while-revalidateserve stale while one refreshesstale data allowed
Probabilistic refreshrefresh before expiry with probabilitymore complex
Background warmingprecompute hot keysmay waste work
Admission controlonly cache keys that prove hotavoids memory pollution

TTL jitter example:

long baseTtlSeconds = 300;
long jitter = ThreadLocalRandom.current().nextLong(0, 60);
long ttl = baseTtlSeconds + jitter;

8. Stale-While-Revalidate

Value shape:

{
  "payload": { "caseId": "C-123", "status": "OPEN" },
  "freshUntil": "2026-07-07T10:05:00Z",
  "serveUntil": "2026-07-07T10:10:00Z",
  "version": 17
}

Decision:

now < freshUntil -> serve
freshUntil <= now < serveUntil -> serve stale and trigger async refresh
now >= serveUntil -> block/rebuild or fail based on route policy

Use only when business allows bounded staleness.

Bad fit:

authorization decision
case finalization state
financial balance after transaction
legal deadline calculation

Good fit:

catalog display
dashboard counters
non-critical profile rendering
search suggestion metadata

9. Hot Key

Hot key means one key or key family receives disproportionate traffic.

Symptoms:

cluster has capacity but one node/shard is overloaded
EngineCPUUtilization high on one node
network out high on one node
latency spikes for one route/tenant
DB is fine but cache latency high

Common sources:

KeyWhy hot
config:globalevery request reads it
tenant:{id}:permissionslarge tenant fanout
catalog:homepagepublic page spike
rate:{tenant}:globalnoisy tenant limiter
case:{id}:summaryviral/internal bulk access

Mitigations:

TechniqueWhen
local in-process cachesmall config, short TTL
key replicationread-mostly hot keys
sharded counterwrite-heavy counters
route-specific batchingrepeated same lookup
CDN/edge cachepublic read-heavy content
precomputed projectionexpensive derived data
tenant isolationnoisy tenant risk

Hot key sharding example for counter:

counter:{name}:shard:0
counter:{name}:shard:1
...
counter:{name}:shard:N

Read sums shards. Write picks shard by random or actor hash.


10. Large Values

Large values cause:

more network bytes
longer serialization/deserialization
higher memory fragmentation risk
slower replication
larger blast radius per miss

Guidelines:

Cache the view you need, not the entire aggregate graph.
Prefer stable schema and compact payload.
Avoid storing huge arrays that change partially.
Consider compression only after measuring CPU trade-off.
Split hot fields from cold fields.

Anti-pattern:

cache key: case:{id}
value: entire case graph + documents + comments + permissions + history

Better:

case:{id}:summary
case:{id}:timeline:page:{n}
case:{id}:permission-epoch
case:{id}:latest-action

11. Connection Operability

Client behavior can break cache even when cache capacity is enough.

AWS client guidance includes finite connection pool, client-side timeout, cluster discovery, retry with exponential backoff and jitter, and server-side idle timeout for idle connection buildup.

Production rules:

[ ] Use bounded connection pool.
[ ] Set connect timeout and command timeout.
[ ] Retry only safe commands.
[ ] Add exponential backoff with jitter.
[ ] Avoid unbounded async concurrency.
[ ] Handle MOVED/ASK/topology change if cluster mode enabled.
[ ] Avoid DNS cache settings that prevent failover discovery.
[ ] Emit client-side metrics, not only server metrics.

Connection storm pattern:

cache node failover -> clients disconnect -> all clients reconnect immediately -> new connections spike -> engine/host pressure -> command latency rises -> app retries -> worse storm

Mitigation:

bounded pool + jittered reconnect + circuit breaker + local degraded mode

12. Failover

During failover, expect:

short connection errors
timeouts
retries
possible topology refresh
some in-flight commands ambiguous
read replica promotion behavior
client reconnect storm

Application policy:

Cache purposeDuring failover
derived read cachebypass cache temporarily, read DB with backpressure
session storeretry briefly, then controlled re-auth/degraded UX
rate limiterexplicit fail-open/closed per route
distributed lockassume lock state uncertain; require fencing/durable verification
cache invalidation workerretry; idempotent delete; reconcile later

Do not assume failover is invisible to the application. Design the path.


13. Cache Hit-Rate Collapse Runbook

Symptoms:

CacheHitRate drops
DB QPS rises
API latency rises
Evictions may or may not rise

Immediate actions:

1. Check deployment timeline for key/TTL/schema change.
2. Check evictions and memory pressure.
3. Check invalidation event volume.
4. Check whether cache warming/backfill was disabled.
5. Check whether one tenant/key family caused churn.
6. Apply DB protection: throttle expensive routes, reduce worker concurrency, enable degraded cache path.
7. Restore previous key format or rollback deployment if needed.

Questions:

Is this cache empty, invalidated, evicted, bypassed, or using the wrong key?

14. Eviction Spike Runbook

Symptoms:

Evictions > 0 or sharply increasing
memory usage high
hit rate slowly or suddenly drops

Actions:

1. Identify whether eviction policy is expected.
2. Check memory usage per node/shard, not only cluster aggregate.
3. Check key cardinality and value size change after deployment.
4. Reduce TTL for low-value keys only if memory is dominated by stale data.
5. Disable or slow warming/backfill jobs.
6. Scale node memory or shard count if growth is legitimate.
7. For session/coordination keys, move critical state out of eviction-prone cache or isolate cluster.

Important:

Eviction of cache-aside data is a performance problem.
Eviction of session/lock/rate state can be correctness or security problem.

15. Hot Key Runbook

Symptoms:

one shard/node high CPU/network
route latency skewed
tenant-specific latency spike
command latency high despite normal aggregate capacity

Actions:

1. Use app telemetry to identify route + cache key family.
2. Compare per-node EngineCPUUtilization and network metrics.
3. Check whether key is read-hot or write-hot.
4. For read-hot: local cache, key replication, CDN, precompute.
5. For write-hot: sharded counter, queue aggregation, rate limit, redesign key.
6. Add tenant-level protection if one tenant dominates.

Do not blindly scale the cluster if only one key is hot. More capacity may not help unless traffic is redistributed.


16. Stampede Runbook

Symptoms:

miss spike followed by DB spike
same expensive query repeated
traffic aligned with TTL expiration
latency wave every N minutes

Actions:

1. Add TTL jitter.
2. Add request coalescing for hot keys.
3. Enable stale-while-revalidate where safe.
4. Protect DB with bounded concurrency.
5. Warm critical keys gradually, not all at once.
6. Add per-key rebuild metrics.

Request coalescing local sketch:

CompletableFuture<Value> existing = inFlight.get(key);
if (existing != null) return existing;

CompletableFuture<Value> created = new CompletableFuture<>();
CompletableFuture<Value> previous = inFlight.putIfAbsent(key, created);
if (previous != null) return previous;

try {
  Value value = loadFromDb(key);
  cache.set(key, value, ttlWithJitter());
  created.complete(value);
  return created;
} catch (Throwable t) {
  created.completeExceptionally(t);
  throw t;
} finally {
  inFlight.remove(key);
}

17. Stale Data Incident Runbook

Symptoms:

user sees old state
cache value version older than DB version
invalidation worker lag
event replay happened

Actions:

1. Compare source-of-truth version vs cached version.
2. Check invalidation event was emitted after DB commit.
3. Check EventBridge/SNS/SQS/Lambda delivery and DLQ.
4. Check out-of-order invalidation if multiple updates occurred.
5. Delete exact keys or bump namespace epoch.
6. Reconcile affected aggregates.
7. Add version guard to cache set to avoid stale overwrite.

Stale overwrite prevention:

Only write cache if incoming version >= cached version.

For Redis/Valkey, use Lua if compare-and-set is required atomically.


18. Command Cost and Slow Commands

Expensive Redis-like commands can behave like table scans.

Avoid in request path:

KEYS *
large SMEMBERS
large LRANGE
large HGETALL for huge hash
unbounded Lua scripts
blocking operations without isolation

Prefer:

SCAN with bounded operational tooling only
bounded page sizes
small hashes
purpose-specific keys
precomputed projections

Runbook question:

Did we accidentally introduce an O(N) command into a hot request path?

19. Cache as Blast-Radius Boundary

Separate clusters when blast radius differs.

StateIsolation recommendation
public content cachecan share lower-criticality cache
session stateisolate or use MemoryDB/DynamoDB if critical
rate limiterisolate if limiter failure can affect all APIs
authorization cacheisolate + short TTL + epoch
distributed lock/leaseprefer durable store; isolate if used
feature flags/configlocal cache + highly available source

One shared Redis cluster for everything is operationally convenient and architecturally dangerous.


20. Alarm Design

Good alarm:

Condition: CacheHitRate drops below baseline AND DB read QPS increases AND API latency increases
Action: investigate cache miss storm, protect DB

Bad alarm:

Condition: CPU > 80% for 1 minute
Action: panic

Useful composite alarms:

AlarmSignal
cache-miss-impacthit rate down + DB QPS up + p95 up
eviction-riskmemory high + evictions increasing
connection-stormnew connections spike + errors/timeouts
hot-shardone node engine CPU much higher than peers
replica-riskreplication lag high + read traffic on replica
stale-projection-riskinvalidation queue age high + stale read complaints

21. Load Test Matrix

Test beyond happy path:

[ ] Cold cache startup at peak traffic.
[ ] Simultaneous TTL expiry for hot keys.
[ ] One tenant generates 10x traffic.
[ ] Cache unavailable for 2 minutes.
[ ] Node failover while traffic is high.
[ ] DB slower than usual during cache miss storm.
[ ] Invalidation worker DLQ grows.
[ ] Deployment changes key schema.
[ ] Large value accidentally cached.
[ ] Connection pool maxed out.

Measure:

API p50/p95/p99
cache latency
hit rate
DB QPS/latency
connection count
evictions
engine CPU
error rate
recovery time

22. Security and Compliance Operability

Cache can leak sensitive data if treated casually.

Checklist:

[ ] TLS enabled where required.
[ ] Auth/ACL/secrets managed and rotated.
[ ] Key/value does not contain unnecessary PII.
[ ] Logs do not print raw cache values.
[ ] Session keys are random and non-guessable.
[ ] Authorization cache has short TTL/epoch.
[ ] Data deletion policy includes cache invalidation.
[ ] Incident runbook includes forced namespace invalidation.
[ ] Cross-tenant key names cannot collide.

For regulatory systems, cache content may affect evidence, authorization, or user-visible decision state. Document whether cached state is authoritative or derived.


23. Production Readiness Checklist

[ ] Every cache namespace has owner, source of truth, TTL, and staleness budget.
[ ] Critical coordination state is not mixed with best-effort read cache.
[ ] Eviction policy is intentional.
[ ] Memory usage, evictions, hit rate, engine CPU, connections, network, and replication lag are monitored.
[ ] Client has bounded connection pool.
[ ] Client has sane connect/read timeout.
[ ] Retries use exponential backoff with jitter.
[ ] Cache failover behavior is tested.
[ ] Cache unavailable path is defined: fail-open, fail-closed, or degraded.
[ ] Stampede protection exists for hot expensive keys.
[ ] TTL jitter exists for high-volume keys.
[ ] Hot key detection uses app telemetry, not only cache metrics.
[ ] Invalidation pipeline has DLQ, retry, and reconciliation.
[ ] Stale overwrite is prevented with version guard where needed.
[ ] Runbooks exist for hit-rate collapse, eviction spike, hot key, connection storm, stale data, and failover.

24. Anti-Patterns

  1. One shared cache cluster for sessions, locks, rate limits, and random read cache.
  2. No TTL because “the data rarely changes”.
  3. TTL-only invalidation for authorization-sensitive data.
  4. Ignoring evictions because “it is only cache”.
  5. Scaling cache cluster to fix a single hot key.
  6. Caching huge aggregate graphs.
  7. Using KEYS * in production tooling.
  8. Unbounded connection pools from ECS/Lambda workers.
  9. Fail-open/fail-closed determined by accidental exception behavior.
  10. No load test for cold cache or cache failover.

25. Key Takeaways

  1. Cache operability must be designed with the database and application path together.
  2. Evictions, hot keys, connection storms, and stampedes are different incidents with different fixes.
  3. Aggregate cluster capacity can hide per-node/per-shard bottlenecks.
  4. Client behavior is part of cache reliability.
  5. Critical coordination state needs isolation or a stronger store.
  6. A cache that cannot be rebuilt, invalidated, and observed safely is not an optimization; it is hidden state.

26. References

Lesson Recap

You just completed lesson 86 in final stretch. Use the series map if you want to review the broader track, or continue directly into the next lesson while the context is still warm.

Continue The Track

Keep the momentum while the lesson is still fresh. Move backward for review or continue forward into the next concept.