1 Overview
Caching advice travels well because it sounds universal, and that is exactly why so much of it is wrong in practice. A rule that helps a static marketing site can quietly wreck a personalized application, and a technique that saves an origin during a traffic spike can hide bugs for weeks. The myths in this article are not lies; they are simplifications that were true under conditions most teams no longer have. Treating them as laws is how sites end up slow, stale, or both.
The five myths share a common shape. Each one replaces a measurement with a slogan: cache everything, cache forever, purge on every write, trust the hit ratio, and assume the cache is always faster. None of those survive contact with real request diversity, real invalidation needs, or real memory limits. The goal here is not to abandon caching. It is to replace slogans with mechanisms you can reason about, so your decisions follow from your workload rather than from a checklist.
This article walks through where the common advice breaks down, how the underlying machinery actually behaves, the trade-offs you are implicitly accepting, how to implement caching correctly, and how to tell whether it helped. The emphasis throughout is on honest engineering: caches are a bet on reuse, and every bet has a cost when the reuse does not materialize.
2 Where the common advice breaks down
The first myth is that you should cache everything. Caching is only valuable when responses repeat. If most requests carry unique query strings, session tokens, or personalization parameters, a shared cache stores near-duplicates and evicts useful entries to make room. The result is a large cache with a poor hit rate, more memory pressure, and more chances to serve the wrong variant to the wrong user. Selectivity beats coverage.
The second myth is that long TTLs are always better. A long TTL raises the chance a request is served from cache, but it also lengthens the window in which stale or incorrect content is visible. For immutable, fingerprinted assets that is fine. For prices, inventory, permissions, or feature flags it is a correctness problem disguised as a performance win. Freshness is a product decision, not just a tuning knob.
The third myth is that purging on every write keeps everything correct. Purges are network calls with their own latency, failure modes, and fan-out. Purging one logical change can mean invalidating many derived keys, and a partial purge leaves inconsistent state. The fourth myth is that a high hit ratio proves success; a cache can hit often on cheap responses while missing on the expensive ones that actually load the origin. The fifth is that a cache is always faster, which ignores lookup overhead, serialization, and the cost of serving stale data.
3 How the mechanism actually works
A cache is a lookup table keyed by something derived from the request, usually a URL plus selected headers or a computed key. On a hit, the stored response is returned without touching the origin. On a miss, the request goes upstream, the response is stored if it is cacheable, and later identical requests reuse it. Everything hinges on the key: two requests that differ in any way that affects the response must produce different keys, or the cache will serve one user's data to another. Over-specific keys fragment the cache; under-specific keys corrupt it.
Storage is finite, so eviction is always happening. When the working set exceeds capacity, entries are removed by some policy, and the useful ones may leave before they are reused. That is why hit rate depends on request diversity and capacity together, not on cache size alone. A cache holding a million rarely requested objects can perform worse than a small cache holding the thousand objects that dominate traffic.
Freshness is tracked separately from presence. An entry can exist but be expired, at which point the cache either revalidates with the origin or refetches. Revalidation can confirm the stored copy is still valid without transferring the full body, which saves bandwidth but still costs a round trip. Stale-while-revalidate lets a slightly stale response be served while a refresh happens in the background, trading a small freshness window for smoother latency. Invalidation, whether by TTL expiry, explicit purge, or key versioning, is the part most teams underestimate.
4 Trade-offs you are really making
Every caching decision trades freshness, correctness, and simplicity against origin load and latency. Raising the TTL reduces origin traffic and improves response times for repeat requests, but it widens the window where users see outdated data. Shortening the TTL tightens correctness but pushes more requests upstream, which can matter most during the traffic spikes when you least want the origin stressed. There is no setting that maximizes both; you are choosing where the pain lands.
Key design carries its own trade-off. Broad keys give high hit rates but risk serving the wrong variant, especially when personalization, locale, device class, or authorization affects the response. Narrow keys are safer but fragment the cache, lowering the hit rate and increasing memory needs. The honest approach is to include in the key exactly the dimensions that change the response, and to measure whether the resulting hit rate justifies the memory.
Invalidation strategy is the third axis. Short TTLs are simple and self-healing but imprecise. Explicit purges are precise but add coupling between your write path and your cache, plus failure handling when a purge does not land. Versioned or content-addressed keys avoid purges entirely by making new content a new key, at the cost of accumulating old entries until eviction. Each choice shifts complexity somewhere: into freshness, into the write path, or into storage.
5 Implementing it correctly
Start by classifying responses rather than caching uniformly. Immutable, fingerprinted assets can take long TTLs and be cached aggressively. Public pages that change occasionally can take moderate TTLs with revalidation. Personalized or sensitive responses usually should not enter a shared cache at all, or should be keyed so precisely that sharing is impossible. This classification is the single highest-leverage step, because it prevents the most damaging failure mode: serving one user's data to another.
Next, design keys deliberately. Decide which request attributes genuinely change the response and encode them consistently. Normalize query parameters so trivial ordering differences do not create duplicate entries. Strip tracking parameters that do not affect content. Where content changes, prefer versioned keys over purges so that new content appears under a new key and old entries age out naturally. Reserve explicit purge for the bounded cases where versioning is impractical.
Then set TTLs from the product's freshness requirement, not from a desire to maximize hit rate. Add stale-while-revalidate where a brief staleness window is acceptable, so users get fast responses while refreshes happen in the background. Instrument cache status on every response so you can separate hits, misses, revalidations, and bypasses. Finally, test invalidation explicitly: change content, confirm the change is visible within the promised window, and verify that a failed purge does not leave permanent staleness. Correctness under failure is part of the design, not an afterthought.
6 Measuring whether it helped
A single hit ratio is a weak signal because it treats all responses as equal. A cache that hits on tiny, cheap responses and misses on the few expensive ones may show a flattering ratio while doing little for origin load. Measure hit rate weighted by origin cost, or track origin request volume and egress alongside the ratio. The question is not how often the cache was used, but how much work it removed.
Watch latency distributions rather than averages. Caching should reduce tail latency for repeat requests, but a cache lookup adds a small fixed cost to every request, including misses. If misses dominate, that overhead is pure loss. Compare percentiles for cacheable and non-cacheable traffic separately, and track revalidation rates, because frequent revalidation means entries are expiring before they are reused and the TTL may be too short for the access pattern.
Finally, measure correctness. Track how often stale content is served, how long after a write the change becomes visible, and whether purge operations fail. A cache that improves latency while serving outdated prices or permissions is not a success. Tie the metrics back to the trade-off you chose: if you accepted a freshness window, verify the window is what you promised. Revisit the classification and TTLs as traffic patterns change, because a configuration that helped last quarter can quietly become the reason the origin is overloaded now.
7 Frequently asked questions
Should I cache everything to be safe? No. Caching only pays off when responses repeat. Caching unique or personalized responses wastes memory, lowers the effective hit rate, and increases the risk of serving the wrong variant. Cache selectively, based on how often a response is reused and how expensive it is to produce.
Are long TTLs always better? They raise hit rates but extend the period during which stale content is visible. Use long TTLs for immutable, fingerprinted assets and short TTLs, revalidation, or versioned keys for content that changes. The right TTL comes from the freshness the product requires, not from a target hit ratio.
Is purging on every write the correct approach? It is precise but fragile. Purges add latency and failure modes to the write path, and partial purges cause inconsistency. Versioned or content-addressed keys often replace purges entirely by making changed content a new key.
Does a high hit ratio mean caching is working? Not necessarily. Weight hit rate by origin cost and check origin request volume. A high ratio on cheap responses can mask misses on the expensive ones that actually stress the origin.
Is a cache always faster? No. Lookups, serialization, and stale data all have costs. Measure latency distributions and correctness together, and treat caching as a trade-off you manage rather than a switch you flip.