A cache is a copy of an answer stored somewhere faster than the original source, so a system can return it instantly instead of recomputing or re-fetching it. Every cache makes the same trade: speed today for a risk that the copy goes stale tomorrow. Understanding that trade explains most of the bugs engineers casually blame on "a caching issue."

Quick Answer: A cache stores a previously computed answer so the next request skips the expensive work of producing it again. The catch is cache invalidation — knowing when a stored answer is no longer true — which is why caching bugs almost always look like "stale data," not "slow data."

What Is a Cache, Really?

A cache is storage that trades freshness for speed by keeping a copy of something expensive to produce, close to where it's needed. Instead of recalculating a result or re-fetching it from a slow origin, the system checks the cache first and only does the expensive work on a "miss."

Think of it the way you'd think about a whiteboard summary of a long meeting. Reading the whiteboard is instant; re-running the meeting to get the same information is not. The whiteboard is accurate the moment it's written — and increasingly wrong every minute after, if the underlying facts change and nobody updates it.

That's the entire mental model for every cache you'll ever hear about, from a browser tab to a global CDN:

  1. Compute or fetch the expensive answer once.
  2. Store a copy somewhere fast to read.
  3. Serve the copy on subsequent requests instead of repeating step 1.
  4. Decide when the copy stops being true — this fourth step is the hard part.

Caches exist because the two halves of most systems have wildly different speeds. A database query, a machine-learning inference, or a network round-trip to another data center can take tens or hundreds of milliseconds. Reading a value already sitting in memory takes microseconds. Multiply that gap by millions of requests and caching stops being an optimization — it becomes the difference between a product that feels instant and one that feels broken.

Why This Matters Even If You Never Touch the Code

You don't need to implement a cache to be affected by one. As a PM, caching decisions shape three things you do own: perceived performance, the trustworthiness of the data your users see, and the shape of the bug reports that land in your inbox labeled "it's showing the old price" or "the dashboard looks wrong." Once you can name the layer, you can ask sharper questions in a design review instead of nodding along to "it's cached" as if that ends the conversation.

The Three Places Caching Happens (Browser, CDN, Application)

Caching happens at three broad layers — browser, CDN, and application/database — and each one trades freshness for speed at a different distance from the user, which changes how long staleness can survive undetected. Knowing which layer is involved tells you who owns the fix and how fast a correction can propagate.

LayerWhat it storesTypical lifespanWho controls itCommon PM-visible symptom
Browser cacheStatic assets: images, scripts, styles, sometimes whole pagesMinutes to months (set by Cache-Control headers)Frontend engineering, via HTTP headersUser sees an old logo or old UI after a deploy
CDN / edge cacheCopies of pages or API responses served from servers near the userSeconds to hoursInfrastructure/DevOps, via CDN configUsers in different regions see different content simultaneously
Application / database cacheComputed query results, session data, feature flags, pricingMilliseconds to minutesBackend engineering, via cache libraries (Redis, Memcached)Stale price, stale inventory count, "ghost" data after an edit

A request to a cached page can hit all three layers in sequence — browser first, then CDN, then application — and each one can independently decide it already has an answer. That's why the same bug can look different depending on which layer served the stale copy.

Browser Caching: The One Closest to the User

The browser cache stores files your product doesn't need to re-download every time — logos, stylesheets, JavaScript bundles — governed by HTTP headers like Cache-Control and ETag. It's why a page loads instantly on a second visit and why a shipped bug fix sometimes "isn't showing up" for a user until they hard-refresh.

This is the layer non-engineers run into personally most often. "Have you tried clearing your cache?" is really "your browser has a copy of the old version and hasn't been told to check for a new one yet." It's the same freshness-for-speed trade, just visible on your own machine.

Cache Invalidation: The Famous Hard Problem

Cache invalidation is famously hard because a cache has no built-in way of knowing the source data changed — it only knows what it stored and, at best, a timer for how long to trust it. Computer scientist Phil Karlton is widely credited with the line "there are only two hard things in computer science: cache invalidation and naming things," and product teams rediscover why on a regular basis.

The core problem: a cache and its source of truth are two separate copies of the same fact, and nothing forces them to update together. The source can change while the cache keeps confidently serving the old value, because the cache was never asked to check.

The Stale-Price Bug, Concretely

Picture an e-commerce team running a flash sale. The pricing service recalculates and writes a new price to the database at 9:00 a.m. But the product page is served through an application cache with a 15-minute expiry, and a CDN in front of that with its own 5-minute rule.

  1. 9:00 a.m. — Database updated with the new sale price.
  2. 9:00–9:05 a.m. — The application cache still holds the old price (its 15-minute window hasn't expired); it serves that to anyone who asks.
  3. 9:05 a.m. — The CDN's own copy also expires and re-fetches from the application layer, which is still serving the stale application-cache copy.
  4. 9:15 a.m. — The application cache finally expires and reads the true price from the database. Only now does the correct price begin propagating outward.

For fifteen minutes, some customers saw the sale price, some saw the old price, and support started getting tickets about "pricing is broken" — when nothing was broken. Two independent caches, each individually correct in its own logic, combined to produce fifteen minutes of confusing inconsistency. That's the invalidation problem in miniature: no single component was wrong, and the system was still wrong.

The Three Real Strategies for Fighting Staleness

There is no universal fix for invalidation — only trade-offs among a small set of real strategies, each swapping some freshness, complexity, or cost for the others.

  • Time-based expiry (TTL): the simplest approach — store a value and a timer, and stop trusting it after the timer runs out. Easy to implement, but freshness is only ever as good as the timer you picked, as the stale-price bug shows.
  • Event-based invalidation: the source system actively tells the cache "this changed, forget your copy" the moment an update happens. More accurate, but requires every writer to remember to fire that signal — a missed signal is a silent bug.
  • Versioning / cache-busting: attach a version identifier to the cached item (a file hash in a URL, a version number in a key) so a new version is a genuinely new cache entry rather than an update to an old one. Common for static assets; awkward for frequently-changing data like prices.
StrategyFreshness guaranteeImplementation costBest fit
Time-based (TTL)Bounded by the timer, not exactLowContent that tolerates being briefly stale (catalog listings, search results)
Event-based invalidationHigh, if every write path fires itMedium-highData where staleness is costly (prices, inventory, permissions)
Versioning / cache-bustingExact, by designLow-mediumStatic assets, deployed code, immutable content

None of these strategies is "correct" in the abstract — the right choice depends on how expensive staleness is for that specific piece of data versus how expensive it is to keep checking. This is a real product trade-off, not just an engineering one, which is why it belongs in a PRD conversation, not only a pull request.

How to Ask the Right Questions About Caching in a Design Review

The useful PM question isn't "is this cached?" — it's "what happens between the moment the source data changes and the moment every cached copy reflects it?" That single question forces a concrete answer about layers, timers, and invalidation triggers instead of a shrug.

A few follow-up questions turn "it's a caching issue" from a conversation-ender into a conversation-starter:

  1. Which layer is caching this — browser, CDN, or application? (See the table above — the answer changes who can fix it and how fast.)
  2. What's the invalidation strategy — TTL, event-based, or versioned? A TTL of "however long feels right" is a red flag worth probing.
  3. What's the worst-case staleness window, and is that acceptable for this specific data? Fifteen minutes is fine for a blog post; it's a support incident for a live price. 4** Is staleness visible or silent? A stale product photo is harmless. A stale permissions cache that still lets a removed employee access something is a security bug wearing a performance optimization's clothes.

Treating caching as a scoping question rather than a purely technical detail is a habit borrowed from broader technical literacy — the same instinct behind understanding how the web works as a PM mental model and knowing what an API actually is. Caching sits directly on top of both: it's a layer inserted between a request and a response, and the HTTP status codes and methods you already half-recognize (304 Not Modified, Cache-Control, ETag) are the protocol-level vocabulary of exactly this negotiation.

Where Caching Fits in Your Product's Architecture

Caching sits between the API layer and the database layer — it's the thing that answers a request before it ever has to travel all the way to the database and back. Once you can place it on a diagram, "it's a caching issue" stops being an unfalsifiable excuse and becomes a specific, checkable claim about one hop in a request's journey.

This is easier to internalize when you can actually see the request path rather than imagine it. In Prodinja's API Designing tool, you can lay out the endpoints your product exposes and see them as curl-able, spec-backed contracts rather than an abstraction; alongside it, the Data Modelling tool lets you sketch the entities and relationships those endpoints ultimately read from, down to the SQL DDL. A cache is the layer that sits between those two views — visualizing both makes it far easier to reason about where a copy of the data could realistically be sitting stale, instead of treating "the cache" as an unlabeled black box between "the app" and "the truth."

None of that requires Prodinja to simulate the cache itself — it's a structural aid for mapping where staleness could live in a system you're already responsible for scoping requirements against, alongside frameworks like Jobs to Be Done for the "why" and customer journey mapping for the "when" a caching decision actually surfaces to a user.

Key Takeaways

  • A cache stores a computed answer so a system can skip recomputing it — the entire value proposition is speed, purchased by accepting some risk of staleness.
  • Every cache lives at a distance from the truth, and the three common layers — browser, CDN, and application/database — differ in who controls them and how long staleness can persist.
  • Cache invalidation is hard because nothing automatically tells a cache the source changed — Phil Karlton's famous line about invalidation and naming things is a real, decades-old observation, not a joke.
  • The stale-price bug pattern (multiple independent caches, each individually correct) is the most common real-world shape of a caching incident — no single layer is "wrong," yet the combined result is.
  • The three invalidation strategies — TTL, event-based, and versioning — are trade-offs, not a hierarchy; the right one depends on how costly staleness is for that specific data.
  • "Is staleness visible or silent" is the single best triage question for deciding how urgently a caching bug needs fixing.
  • Asking "what's the worst-case staleness window" turns "it's a caching issue" into a specific, falsifiable, schedulable answer instead of a conversation-ending shrug.

Frequently Asked Questions

What is a cache in simple terms?

A cache is a stored copy of an answer — a web page, a database query result, a computed value — kept somewhere fast to read so a system doesn't have to redo the expensive work of producing it again. It trades a small risk of showing outdated information for a large gain in speed.

Why is cache invalidation considered so hard?

Because a cache has no built-in signal that the original data changed — it only knows what it stored and, at best, a timer for how long to trust that. Every invalidation strategy (TTL, event-based, versioning) is really a different guess at when to stop trusting a stored copy, and each guess can be wrong in a different way.

What's the difference between a browser cache and a CDN cache?

A browser cache stores files on a single user's device, governed by response headers like Cache-Control; a CDN cache stores copies on servers geographically close to groups of users, so different regions can technically see different cached content at the same moment. Both sit in front of the application, but they're controlled by different teams and cleared through entirely different mechanisms.

How do I know if a bug is actually a caching issue?

Ask whether the same request returns different results depending on when or where it's made — differing by user, region, or a few minutes' timing is the classic signature of a caching-layer bug rather than a logic bug. If the underlying data is provably correct in the database but wrong on screen, staleness in one of the three layers is the most likely explanation.

Does caching ever cause security problems, not just stale data?

Yes — a permissions or authentication cache that hasn't invalidated after a user's access is revoked can silently keep granting access after it should have been removed. This is why "is staleness visible or silent" matters: a stale product image is a cosmetic bug, but a stale permissions cache is a security incident that happens to be wearing a performance optimization's clothes.