Caching improves performance but introduces stale reads, inconsistency, and complex invalidation. If used carelessly, users see wrong data, decisions are made on old state, or different parts of the system disagree — so the system can behave “wrong” even though each component is working.
Main failure modes
flowchart TB
subgraph Problems["Cache can cause"]
P1[Stale data shown as truth]
P2[Invalidation missed → permanent stale]
P3[Thundering herd on expiry]
P4[Wrong key / collision]
end
Examples
Stale balance — Cache shows old balance; user thinks they have more (or less) than they do.
Missed invalidation — DB updated, cache not invalidated; reads return old value until TTL.
Thundering herd — Cache expires; many requests hit DB at once; DB overload.
Wrong key — Cache key doesn’t include all inputs (e.g. user id); one user sees another’s data.
sequenceDiagram
participant U as User
participant Cache as Cache
participant DB as DB
Note over DB: Balance updated to 100
U->>Cache: Get balance (stale 50)
Cache-->>U: 50
Note over U: User sees wrong balance
Mitigations: Don’t cache data that must be exact (e.g. balance after write). Use correct keys (include user/session). Invalidate on write or use short TTL. Use single-flight or lock to avoid thundering herd on miss.