LearnastraTHE DESIGN COURSE

Understand the building blocks / CHAPTER 12

Caching fundamentals

Use cached copies to reduce work while defining freshness, invalidation, and miss behavior.

Intermediate1h of deliberate study10 questions

Builds on System design building blocks, Functional and non-functional requirements.

By the end, you can
  • Explain hits, misses, eviction, and expiration.
  • Calculate an approximate backend-load reduction.
  • Prevent stampedes and unsafe stale responses.

01Reuse a result without creating a second truth

A customer opens product 42. The database holds the current product record. If every read repeats the same expensive database lookup, the application can save a reusable copy in a cache.

Define the copy before adding it:

  1. Name the entry product:42 so readers of this product find the same copy.
  2. Save the product data and its version inside that entry. Version 7 means a particular saved revision; an update may produce version 8 under the same entry name.
  3. Decide how old the copy may be for this operation. A public description may tolerate delay; permission or the final stock claim may require current state.
  4. Define how a read proceeds when no usable copy exists.

Finding a usable entry is a hit. Having to load or compute the value is a miss. The hit ratio is the number of hits divided by the number of lookups for a stated workload.

Calculate both normal and failure demand:

  1. At 10,000 reads per second and 95% hits, 5% miss.
  2. Assuming one database lookup per miss, 10000 × 0.05 = 500 lookups per second reach the database.
  3. If the database supports 2,000 lookups per second, this warm-cache workload fits.
  4. If every entry disappears, all 10,000 reads may miss. That is five times the database’s useful capacity.

The cache saves repeated work, but adds memory, network operations, and another failure case. A high overall hit ratio can also hide one very expensive miss or one popular entry that overloads its assigned cache machine.

02Follow a hit, a miss, and a write

In a cache-aside design, the application handles a missing entry:

  1. Look up product:42 in the cache.
  2. If a usable copy exists, return it under the operation’s freshness and permission rules.
  3. Otherwise read the product from the database, save a reusable copy, and return the result.

Distinguish three reasons a copy disappears:

  • Expiration ends its permitted reuse after a time limit, called its time to live or TTL.
  • Eviction removes an entry to free cache capacity. Least recently used favors entries read recently; least frequently used favors entries read repeatedly. Implementations may approximate these rules.
  • Invalidation removes or disables an entry after the underlying data changes.

A 60-second TTL does not lock the database record. If the record changes just after a copy is saved, that copy can be stale for almost a minute. Invalidation helps, but does not by itself solve this ordering problem:

  1. A reader loads version 7 from the database, then pauses before saving the cache copy.
  2. A writer saves version 8 in the database.
  3. The writer removes the cached entry.
  4. The reader resumes and saves its older version 7 under product:42.

The old value has returned after removal. To prevent this particular stale fill, the cache update needs information that survives removal:

  1. Retain a marker saying that version 8 is the minimum acceptable version.
  2. When a reader tries to save a copy, check that marker and insert the value as one indivisible operation. Reject version 7.
  3. For this example, retain the minimum-version marker for the product’s lifetime, separately from the cached value’s expiry and eviction. A fill that cannot read that marker must not install an older copy. This costs retained version metadata; removing that evidence along with the value loses the protection.

Use a read or update that establishes current state where correctness demands it. Best-effort invalidation and a short TTL are insufficient authority for a revoked permission or a final inventory claim.

03Control the miss path and choose permitted staleness

Suppose 100 readers request the same popular product after its entry expires. If each immediately queries the database, they repeat the same expensive work. This burst is called a cache stampede.

Control the work in a deliberate order:

  1. Let one application fetch the missing product while the other readers share that in-progress result. This is request coalescing.
  2. Limit how many database fetches run at once across keys. One fetch per key can still overload the source when many different products miss.
  3. Bound how long callers wait. Decide whether each operation may receive an older copy or must fail when a fresh result is unavailable.
  4. Spread future expiration times across keys by adding small variations, called expiry jitter. This reduces simultaneous expirations, but does not merge readers already missing one key.

Other choices need explicit costs:

  • Background refresh can prepare a copy before readers wait, but its work still counts against source capacity.
  • Briefly caching a known absence saves repeated lookups. If a record is created a second into a 30-second negative entry, readers may keep seeing absence until that entry is updated or expires.
  • Keeping extra copies of a popular entry can spread cache load. Every copy adds freshness and invalidation work.
  • Serving an older public view count may be acceptable. Serving an old private access grant after revocation can expose data. A useful hit ratio does not justify that permission failure.

For a cache restart, establish source limits before allowing all misses through. Warm useful entries gradually and test the real cold path. Observe served age, database traffic, refresh errors, and the oldest waiting request as well as hit ratio. The aim is less repeated work while preserving the promised response, including when copies are missing.

A late reader can refill stale data

A late reader can refill stale dataThe reader loads version 7 but has not saved it in the cache. The writer saves version 8 and removes the cache entry. The paused reader resumes and attempts to save version 7. A retained minimum-version marker can reject 7 only if the fill checks that marker as one indivisible operation. Numbered arrows correspond to the connection key below. All connections are directional.Reader RLoads source version7Writer WCommits sourceversion 8InvalidationRemoves cached entryR resumesStill carries version7Cache populationOld version returnsunless rejectedChecked cachefillKeep minimumacceptable version12345A late reader can refill stale dataThe reader loads version 7 but has not saved it in the cache. The writer saves version 8 and removes the cache entry. The paused reader resumes and attempts to save version 7. A retained minimum-version marker can reject 7 only if the fill checks that marker as one indivisible operation. Numbered arrows correspond to the connection key below. All connections are directional.Reader RLoads source version7Writer WCommits sourceversion 8InvalidationRemoves cached entryR resumesStill carries version7Cache populationOld version returnsunless rejectedChecked cachefillKeep minimumacceptable version12345A late reader can refill stale dataThe reader loads version 7 but has not saved it in the cache. The writer saves version 8 and removes the cache entry. The paused reader resumes and attempts to save version 7. A retained minimum-version marker can reject 7 only if the fill checks that marker as one indivisible operation. Numbered arrows correspond to the connection key below. All connections are directional.Reader RLoads source version7Writer WCommits sourceversion 8InvalidationRemoves cached entryR resumesStill carries version7Cache populationOld version returnsunless rejectedChecked cachefillKeep minimumacceptable version12345

Follow the numbered arrows

  1. Reader R → Writer Wsource changes after R read
  2. Writer W → Invalidationdatabase-first invalidation
  3. Invalidation → R resumesreader was still in flight
  4. R resumes → Cache populationlate population attempt
  5. Checked cache fill → Cache populationcompare retained version before saving
A reader pauses while holding version 7. The writer saves version 8 and removes the cached copy. When the reader resumes, it can restore 7. Preventing this requires a checked fill with retained version information, or a read path that establishes the required current state.
Trace the diagram in words
  1. The reader loads version 7 but has not saved it in the cache.
  2. The writer saves version 8 and removes the cache entry.
  3. The paused reader resumes and attempts to save version 7.
  4. A retained minimum-version marker can reject 7 only if the fill checks that marker as one indivisible operation.

DRAW. CALCULATE. EXPLAIN.

Budget a cache restart

20 minutes · guided practice

A service receives 12,000 reads per second. A warm cache has a 96% hit ratio, and the database supports 1,500 lookups per second.

  1. Calculate normal database demand and demand with an empty cache.
  2. Explain how to protect the database during restart.
  3. Trace how a paused reader can restore an old value after a writer invalidates the entry, and explain a real prevention mechanism.
Your self-check
Compare the worked solution
  1. Warm misses are 12000 × 0.04 = 480 database lookups per second.
  2. With an empty cache, up to 12,000 reads per second may miss. That is 12000 / 1500 = 8 times the database limit.
  3. Limit simultaneous database work before the surge arrives. Share fetches for the same key and warm useful entries gradually. Bound waiting; serve an older value only where its freshness and permission rules allow it.
  4. For the race, a reader loads version 7 and pauses. A writer saves version 8 and removes the entry. The reader resumes and saves 7 into the now-empty entry.
  5. To reject that fill, retain a minimum-version marker of 8 and compare it with the proposed value as part of the indivisible fill operation. Retain that marker even when the cached value expires or is evicted. If the marker is unavailable, do not install a copy from an earlier read. A required current read can instead use the database’s suitable read path.
  6. A short TTL can reduce stale reuse time, but it does not prevent the race.

The checkboxes record your own assessment. The worked solution gives you a way to check the reasoning.

RETRIEVE BEFORE YOU REVEAL

Keep the important ideas.

Say the answer aloud, then turn the card over.

CARD 01What must be defined before adding a cache?
  1. Identify the original record.
  2. Define the cache key and saved value.
  3. State the maximum permitted staleness.
  4. Explain the miss and cache-failure paths.

A hit must still satisfy the operation’s permission and correctness rules.

CARD 02How do expiry, eviction and invalidation differ?
  • Expiration ends reuse after a time limit.
  • Eviction frees cache capacity.
  • Invalidation removes or disables a copy after a change.

A paused reader can restore an older value after invalidation unless a checked fill operation prevents it.

CARD 03How do I prevent a stampede?
  1. Share one in-progress fetch for readers of the same missing key.
  2. Limit simultaneous source fetches across keys.
  3. Bound waiting and allow old data only where the product permits it.
  4. Vary future expiration times to avoid many keys expiring together.
Practise this topic in the revision deck ↗

CHECK THE REASONING

Can you explain the choice?

Answer every question, then finish for an immediate score and an explanation for each answer. Aim for 80%, then revisit any gaps.

1 / 10At 10,000 reads/s and 95% hits, what is the simple normal source rate?
2 / 10The cache becomes empty and the source limit is 2,000/s. What can unprotected demand reach?
3 / 10Version 7 loads before a write; version 8 commits and invalidates; the old reader then populates 7. What happened?
4 / 10A popular expired key has 100 simultaneous readers. What directly reduces duplicate source queries?
5 / 10What distinguishes eviction from expiration?
6 / 10Product 42 changes just after a 60-second cached copy is populated. What can happen?
7 / 10Known absence is cached for 30 seconds; the record is created a second later. What is the risk?
8 / 10A stale value controls access to a private document. Which choice fits revocation requirements?
9 / 10Why can one hot key overload a cache node despite a low fleet average?
10 / 10What should a cache evaluation include beyond hit ratio?
0 of 10 answered

CLOSE THE LOOP

Explain it without the page.

Summarise the mechanism, one trade-off, and one failure mode. Then mark this chapter complete.