Cache Placement Read Paths and Write Strategies

Caching and Failure Recovery · 40 min

System Design · Module 6 · Lesson 1 of 4 · 40 min

Cache Placement Read Paths and Write Strategies

Choose where a cache belongs, trace cache-aside, and compare read-through write-through write-back and write-around responsibilities.

A cache design starts with the cost it removes, the authoritative store and the freshness contract.

01 The idea

The problem this lesson solves

A cache stores a reusable result so the system can avoid repeating more expensive work. That sounds simple until the original value changes, the cached value disappears or the cache becomes unavailable. The first design decision is therefore not “which cache product?” It is which result may be reused, who owns the truth, and how reads and writes move between those copies.

You should recognize the application, the database and the request path. Treat the database as the authority unless explicitly stated otherwise.

Source of truthThe authoritative state used to decide the correct durable value.
Cache-asideThe application checks the cache and loads the backing store on a miss.
Write-backAcknowledging a cached write before persisting it to the backing store under the chosen contract.

02 Worked example

Branch on a cache hit or miss

Cache-aside hit and miss branchesApplicationGET /r/a7Cache lookupIs a7 available?HitMissReturn copySkip databaseRead databaseFill then returnCache-aside hit and miss branchesApplicationGET /r/a7Cache lookupIs a7 available?HitMissReturn copySkip databaseRead databaseFill then return
A hit returns the cached copy. Only a miss loads the database; an eligible result then fills the cache for later reads.
1
Request a7The app needs one code-to-destination mapping.
2
Check the cacheA hit returns the permitted copy; a miss is a separate branch.
3
Load the authorityOn a miss, read the database and distinguish absent from unavailable.
4
Fill for reuseWrite an eligible value with its freshness policy for later requests.

03 The method

Understand the mechanism

Choose the cache boundary and authority

For a short-link lookup, the database owns code a7’s destination and the cache stores a permitted copy. Losing the cache should cause extra reads, not loss of the only accepted mapping. This relationship differs from using a memory store as the authoritative database.

Caches can live in the browser, at an edge, inside an app process or in a shared service. A local cache avoids a network hop but each app has its own copies and memory budget. A shared cache centralizes more reuse but introduces network latency and a shared dependency.

Choose what is cached: a database object, a query result, an authorization decision or an HTTP representation. Each has different keys and invalidation requirements. Caching a whole user-specific response under only a public path can expose one user’s data to another.

A key should include every dimension that makes results non-interchangeable, such as tenant, resource id, representation version or relevant query parameters. Do not include arbitrary unbounded variation without a memory policy, and do not assume a difficult-to-guess key replaces authorization.

Walk cache-aside through hit, miss and failure

In cache-aside, the application checks the cache. On a hit, it returns the eligible cached value. On a miss, it asks the authoritative store, then stores an eligible result for later reuse. The application owns the orchestration.

For a7, a hit avoids a database lookup. A miss is not an error by itself; it is an expected branch. The application reads the mapping and can fill a7 with the destination and expiry policy before returning. Decide whether a cache-fill failure should prevent an otherwise valid read from succeeding.

An authoritative “not found” is different from a database timeout. A short-lived negative cache entry may reduce repeated lookups for confirmed absence. Caching “missing” after a timeout would turn temporary unavailability into a false data result.

Concurrent misses can all load the same key. Cache-aside by itself does not combine them. That creates the stampede problem explored later. Start with the basic read path, then add coordination only where the workload requires it.

Distinguish read-through from application-managed loading

In read-through, a cache layer or library invokes a loader when a value is absent. The caller asks that layer for the value rather than writing the miss orchestration at every call site. The authority and freshness questions still exist.

Centralized loading can make policy consistent, but it can also hide expensive remote work behind an innocent-looking get. Document whether the call can block, which failures it returns and whether concurrent misses are coalesced.

Read-through does not mean every key is always warm or that the loader can safely fetch unlimited values at once. It needs capacity limits, timeouts and a policy for absent or failed loads just as cache-aside does.

Choose based on ownership of the loading code and the operations supported by the implementation. Avoid treating the terms as performance guarantees. Two systems using the same pattern name can behave very differently during an origin outage.

Compare write-through, write-back and write-around

Write-through routes a write through a layer that updates the authoritative store and cache according to its contract before reporting the chosen completion outcome. It can make newly written data available in cache, but the two systems still have failure-ordering questions unless their implementation supplies a stronger atomic boundary.

Write-back, also called write-behind, acknowledges according to the cache or buffering layer’s contract and propagates to the durable authority later. It can absorb or combine writes, but the buffer now holds important accepted work. Persistence, replication, ordering, replay and recovery become correctness requirements.

Write-around writes to the authority without populating the cache with every write. A later read can load the value. This can avoid polluting a read cache with data that will not be read soon, but existing cached copies still need an update or invalidation policy.

For a first mutable short-link design, database-first writes with an explicit cache policy are easier to reason about than introducing a write-back authority. The choice is not universal; the lesson is to follow what a success acknowledgment promises at every step.

Define freshness before optimizing writes

If a destination is immutable, an eligible cached mapping can be reused under a relatively simple expiry policy. If owners can edit or revoke destinations, a reader may receive an older value unless the system coordinates or bypasses copies.

A TTL controls the lifetime of an entry from its insertion or refresh. It does not automatically measure time since the latest database update. A delayed reader can fill an old value after an update, and multiple cache layers can extend the observed path in different ways.

State the required freshness per operation. Public redirects may permit a documented stale window, while an owner’s immediate verification after an edit may use an authoritative path. Security-sensitive revocation may require stronger guarantees than ordinary content freshness.

This choice belongs in the API and product contract. A cache can be technically healthy and still return a value the user is no longer allowed to act on. Faster incorrect results are not a performance improvement.

Evaluate total cost, not hit rate alone

A hit has a cost: key computation, serialization, lookup latency and network transfer for a shared cache. A miss has those costs plus origin work and possibly a fill. If the origin lookup is already cheap and reuse is low, adding a cache can make the path more complex without meaningful benefit.

Hit ratio also hides request value. A cache might serve many tiny cheap hits while the expensive queries all miss. Measure saved origin work, latency distribution, transferred bytes, memory and recovery load.

Local plus shared caching can reduce shared-store traffic, but it introduces another invalidation layer. If A’s local value expires later than the shared entry, deleting the shared key alone will not make A fresh. Model each copy’s lifetime and ownership.

Test empty, partially warm and failed-cache states. A design that works only at its best observed hit ratio has outsourced reliability to a fragile assumption. The recovery path is part of the cache architecture from the beginning.

Guided tutorial

  1. Trace the four outcomes

    For a7, write cache hit, cache miss with database value, cache miss with confirmed absence, and cache miss with database timeout. The first returns a copy; the second may fill and return; the third may use a deliberate negative-cache policy; the fourth must remain an unavailable outcome.

  2. Design a safe key

    Assume mappings are scoped by tenant. Use the complete tenant and code identity plus any representation version needed by the application. Explain why code alone could return another tenant’s data. Reapply authorization where the operation requires it.

  3. Compare write acknowledgments

    Draw database-first and write-back timelines. Mark the exact point the caller receives success and the failures that can occur afterward. For write-back, identify the durable buffer and replay mechanism needed to avoid losing acknowledged work.

  4. Test the cold path

    Set the cache to empty in a practice trace and send several simultaneous requests for a7. Count the origin loads under basic cache-aside. Keep that count for the recovery lesson, where same-key coalescing will change it.

Cache-aside pseudocode

value = cache.get(scoped_key)
if value is present:
    return value
result = authoritative_store.lookup(code)
if result is a cacheable authoritative result:
    cache.set(scoped_key, result, ttl)
return result

Check your result

A hit performs no database lookup. A miss consults the authority and fills only an eligible result. An unavailable database must not be cached as an authoritative missing code.

04 Cheat sheet

Review the decisions

Use this table to explain the mechanism and its limit without memorizing a product name.

Choice or conceptRememberCheck
Cache-asideApplication loads missesConcurrent fill and invalidation races
Write-throughWrite path maintains cache and storeCross-system partial failure still needs a contract
Write-backPersistence is deferredPending changes can be lost without durable recovery
Write-aroundWrite directly to backing storeExisting cached copies still need a policy

05 Where & why

Check the primary references

Use official references for protocol and implementation details. The questions here are teaching prompts.

Primary reference
HTTP caching semantics

Read HTTP caching semantics

Primary reference
Redis SET and expiration options

Read Redis SET and expiration options

Primary reference
Redis eviction policies

Read Redis eviction policies

State the implementation version and the workload assumptions when defending your own design.

06 Interview questions

Explain the reasoning out loud

Answer before opening the explanation. The questions progress from vocabulary to decisions and failure behavior.

What does Source of truth mean?
The authoritative state used to decide the correct durable value.
What does Cache-aside mean?
The application checks the cache and loads the backing store on a miss.
What does Write-back mean?
Acknowledging a cached write before persisting it to the backing store under the chosen contract.
Why not cache an origin timeout as not found?
The timeout does not establish absence. Caching it as a negative result can hide valid data and turn an outage into persistent wrong answers.
How does local cache differ from distributed cache?
Local cache avoids a network hop but each process has its own copy and cold-start behavior. A distributed cache shares entries while adding a dependency and network cost.
Who loads a cache-aside miss?
The application explicitly reads the authoritative store and fills the cache. The cache service does not infer that relationship.
Is write-through automatically atomic?
No. The system needs an explicit acknowledgment and recovery contract for partial failures across cache and store.
When is write-back risky?
When the acknowledged data is not yet durable enough for the required failure model. Pending changes need persistence and recovery if they must survive cache loss.

07 Practice problems

Practice a new case

Solve the new cases before revealing hints. Complete worked solutions follow the set.

Place the cache

Easy
Choose a cache location to avoid repeated origin downloads of a public versioned image.
Show the hint
Consider serving near clients.

Name the authority

Easy
In cache-aside for order status, identify which store decides the durable status.
Show the hint
A copy is not automatically authoritative.

Build a key

Medium
Design key inputs for a tenant’s translated product description.
Show the hint
Different representations must not collide.

Partial write

Medium
Write-through updates the database then times out writing the cache; state what the contract must resolve.
Show the hint
One operation may already be durable.

Negative result

Medium
A link is created after a cached “not found”; explain the resulting user symptom.
Show the hint
The negative copy can outlive the absence.

Strategy review

Hard
Choose a cache strategy for public article summaries and compare it with accepting financial balances into an evictable write-back cache.
Show the hint
The durability and freshness requirements differ.

Worked solutions

1. Place the cache

A CDN with a correct public/versioned cache policy can avoid origin downloads; browser caching can remove later network requests too.

2. Name the authority

The durable order store is authoritative under this design. The cache is a representation with an explicit freshness rule.

3. Build a key

Include tenant id, product id, locale and any version needed by the invalidation policy. Authorization and cache eligibility remain separate checks.

4. Partial write

Specify acknowledgment, retry identity and invalidation/recovery behavior. Do not claim atomic success across the two independent operations without coordination.

5. Negative result

Reads can keep returning missing until invalidated or expired. Choose short negative lifetimes and creation-path invalidation where appropriate.

6. Strategy review

Cache-aside can suit replaceable summaries with bounded staleness. An acknowledged financial state needs explicit durable authority and recovery; an evictable pending copy without those guarantees is not a sufficient write contract.