CodingNic

Caching Strategies

What Belongs in a Cache

Caching Strategies 10 min read

What Belongs in a Cache

Objectives

By the end of this lesson, you should be able to:

  • Measure the real cost of repeating an expensive operation unnecessarily
  • Identify what kind of data is a good candidate for caching
  • Identify what kind of data is a bad candidate, and explain why

💡 Why this matters: Every database query in this track, Course 2’s Prisma and Mongoose queries included, hits a real database, every single time, even for data that barely changes between requests. Caching skips that repeated cost, for the data where it’s actually safe to.

⚠️ A note on verification: every snippet and every output in this lesson was actually run.

An Expensive Operation

javascript
// Simulates a genuinely expensive database query, an artificial 200ms delay.
const users = { 1: { id: 1, email: 'erin@example.com', bio: 'Backend developer' } };

async function fetchUserFromDatabase(id) {
  await new Promise((resolve) => setTimeout(resolve, 200));
  return users[id];
}

200 milliseconds is a deliberately exaggerated stand-in, a real slow query, a complex join across several tables, an aggregation over a large dataset, can genuinely take that long, or longer, under real load.

Paying That Cost Every Time

javascript
const start1 = Date.now();
await fetchUserFromDatabase(1);
console.log(`First fetch: ${Date.now() - start1}ms`);

const start2 = Date.now();
await fetchUserFromDatabase(1);
console.log(`Second, identical fetch: ${Date.now() - start2}ms`);
text
First fetch: 200ms
Second, identical fetch: 201ms
Third, identical fetch: 200ms

The exact same user, requested three times, the exact same 200ms cost, paid three separate times, nothing about the second or third request was actually different from the first, the data hadn’t changed, the query hadn’t changed, only the cost was repeated, unnecessarily.

What Makes Good Cache Data

Data that’s expensive to compute or fetch, and doesn’t need to be perfectly, instantaneously fresh, a user’s profile information, a list of product categories, a computed report that only needs to update every few minutes, all good candidates, the cost of being slightly stale is low, and the cost of recomputing constantly is high.

What Makes Bad Cache Data

Data that changes on every request, or where staleness is genuinely dangerous, a bank account balance immediately after a transfer, whether a specific rate-limit quota (Course 3, Module 6) has been exceeded right now, an authorization check deciding whether a specific request should be allowed at all, caching these either provides no real benefit (constantly changing data invalidates immediately anyway) or actively creates a security or correctness problem, a cached “you’re allowed to do this” answer served after the actual permission changed is a real bug, not just an inconvenience.

The Real Trade-Off

Caching trades a small risk of staleness for a large reduction in load and latency, that trade is worth making constantly, for the right data, and actively dangerous for the wrong data, this module’s remaining lessons build the actual mechanism, Redis, and the pattern, cache-aside, but choosing what to cache is the decision every one of them depends on getting right first.

Try It

  1. Run fetchUserFromDatabase three times in a row, and confirm the timing shows no improvement between calls, exactly the problem caching solves.
  2. List two pieces of data from Course 3’s Notes API that would be reasonable to cache, and explain why staleness wouldn’t be dangerous for either.
  3. List one piece of data from Course 3’s Notes API that should never be cached, and explain specifically what could go wrong if it were.

Recap

  • Repeating an expensive operation for identical, unchanged data pays its full cost every single time, confirmed here with a genuinely measured, repeated 200ms fetch.
  • Good cache candidates are expensive to compute and don’t need to be perfectly fresh, user profiles, category lists, computed reports.
  • Bad cache candidates change constantly, or where staleness creates a real security or correctness problem, authorization decisions and real-time balances among them.

Next lesson: Redis, and the cache-aside pattern, actually building the caching layer this lesson argued for.