The Complete Guide to Cache Invalidation for System Design Interviews
Master cache invalidation for system design interviews. Learn TTL, write-through, write-around, write-back, and how to balance freshness with performance.
This blog demystifies the cache consistency problem and explores popular cache invalidation strategies. It covers Time-to-Live (TTL) expirations and write policies like write-through, write-around, and write-back caching – explaining how each works and when to use them.
They say there are only two hard things in Computer Science: cache invalidation and naming things.
That famous joke highlights a real challenge – keeping cached data in sync with the source of truth.
Caching can supercharge application performance by storing frequently accessed data in memory; however, the moment the underlying data changes, the cached copy becomes stale.
The cache consistency problem is all about ensuring users don’t see out-of-date information.
In this blog, we’ll break down how to solve this using cache invalidation strategies like TTL expiration and various write policies.
By the end, you’ll know how write-through, write-around, and write-back strategies work and when to use each to balance speed with accuracy.
Why Cache Invalidation Matters
Imagine you update your profile picture, but your friend still sees the old one – the app is probably serving a cached version!
Without proper invalidation, caches can return stale data, leading to inconsistencies and a poor user experience.
Cache invalidation means removing or updating outdated data in the cache so only fresh data is served.
This is critical for data accuracy: if the database (source of truth) has new info, the cache should either update or get out of the way.
The challenge is doing this efficiently – invalidating too frequently can hurt performance, but invalidating too slowly risks inconsistency.
Let’s explore strategies to get it just right.
Strategy 1: Time-to-Live (TTL) Expiration
Time-to-Live (TTL) is a simple but powerful invalidation strategy.
Every cache entry gets an expiration time (TTL); when time’s up, the entry is considered stale and will be refreshed on the next access.
How it Works
When you put data in the cache, you attach a TTL (say 60 seconds).
The cache will serve that data until the TTL expires.
After expiration, the next request triggers fetching fresh data from the database and the cache is updated.
Why use TTL
It’s easy to implement and great for data that changes periodically or isn’t mission-critical fresh.
You don’t have to manually track updates – stale entries fix themselves by expiring.
Example
A weather app might cache the forecast with a 30-minute TTL.
Users get fast responses, and every half-hour the data refreshes to stay current.
Similarly, many websites set TTLs of hours or days for content that updates infrequently, ensuring eventual consistency without constant writes.
Pros & Cons
TTL is simple and robust – even if you forget to explicitly invalidate something, it will expire on its own. This guards against bugs where an update doesn’t clear the cache.
However, choosing the right TTL duration is tricky: too long and users may see stale data; too short and you lose the performance benefits as data expires before it’s actually outdated.
There’s no universal value – it depends on how often your data changes and how fresh it needs to be.
When to Use TTL
Almost always!
A good practice is to apply a TTL to all cache keys (except perhaps those updated via write-through) as a safety net.
Use longer TTLs for data that rarely changes, and short TTLs of a few seconds for rapidly changing data where absolute freshness isn’t critical but you want to reduce load.
TTL is the go-to strategy when you prefer simplicity and can tolerate eventual consistency (e.g. showing slightly old data for a brief time).
It’s also common to combine TTL with other strategies – for instance, even if using write-through, a TTL can serve as a backup to catch any inconsistency that slips through.
Strategy 2: Write-Through Caching
In a write-through cache policy, every time data is written to the database, it’s immediately written to the cache as well.
This proactive approach ensures the cache is always up-to-date with the latest writes.
How it Works
On any create/update/delete operation, the system writes the data to the database and updates the cache at the same time, in the same transaction or workflow.
The user’s write operation isn’t considered complete until both the DB and cache are updated.
This means subsequent reads can be served from cache confidently, since the cache has the newest data.
Why Use Write-through
It avoids cache misses on recently written data.
If you know a piece of data will be read often after it’s written, write-through keeps it in cache ready to go.
It also simplifies consistency – you rarely serve stale data because updates propagate to cache immediately.
Example
Think of a popular article’s view count.
Every time a user views the article, you update the view count in the database and simultaneously update the cached value.
This way the next reader sees an up-to-date view count without waiting for the cache to catch up.
Another example is a leaderboard in a game: when scores update, the cache is updated too, so players always see the latest rankings.
Pros
Strong consistency – the cache and database are always in sync by design.
Users rarely, if ever, see stale info.
Also, recovering from failures is simpler: since every write went to the database, a cache crash doesn’t lose data.
Cons
Slower writes – every write operation does twice the work (DB + cache), adding latency on the write path.
If your application has high write throughput, write-through can become a bottleneck.
It can also lead to cache pollution: data that was written and cached might never be read, filling up cache space unnecessarily.
When to Use Write-through
Use it when read performance and consistency outweigh write latency.
For data that is read frequently and must always be fresh (user profiles, account balances), write-through is a safe choice.
It’s common in systems where stale data could cause errors or bad user experience.
Write-through is also a good strategy in system design interviews to mention when discussing how to keep cache in sync – it shows you favor correctness.
However, if writes are very frequent and the data isn’t always read (or slight staleness is acceptable), you might consider other approaches to reduce the write overhead.
Strategy 3: Write-Around Caching
Write-around caching takes a different approach: on data write, skip the cache entirely and write only to the database.
The cache is updated later, only when that data is read.
Essentially, it “rounds around” the cache on write operations.
How it Works
When an update or insert happens, you directly write to the primary data store (database) and do nothing to the cache (aside from perhaps invalidating the old cache entry if one exists).
The next time a user tries to read that data, the cache will miss, then the system fetches the new data from the DB, returns it, and caches it at that point.
From then on, reads are fast until it expires or gets evicted.
Why Use Write-around
It reduces cache clutter.
If you have data that gets written but not read soon (or ever), write-through would unnecessarily load it into the cache.
Write-around avoids this scenario, preventing the cache from being filled with data that isn’t actually hot.
This can improve overall cache efficiency by reserving space for more frequently accessed items.
Example
Suppose you run an e-commerce site and a rarely viewed product’s details are updated.
With write-around, you update the database record but leave the cache alone.
If no one views that product page soon, you’ve saved cache capacity.
If someone does request it later, they might face a slightly slower response, but then the product info gets cached for subsequent requests.
Pros
Prevents cache pollution by keeping seldom-accessed data out of the cache by default.
It’s ideal for workloads with low read-after-write locality, i.e. when writes don’t tend to be followed by immediate reads.
Write-around can also lower the write load on the cache layer, since writes go straight to the DB.
Cons
The obvious downside is read latency for recently written data.
Right after a write, the cache doesn’t know about the change.
So the first read for that data will be a miss and must fetch from the slower database, which could hurt user experience for that request.
If the data is read very soon after a write, users might encounter a cache miss penalty.
When to Use Write-around
Consider it when writes are frequent but reads are rare or unpredictable for the same data.
It’s a good fit for scenarios where caching every write is wasteful – for example, logs, audit records, or infrequently accessed records that still get written to.
Also, if your cache capacity is limited, write-around helps prioritize it for truly hot data.
Keep in mind that if you do need to read the data shortly after a write, write-around will have a cache miss penalty.
Strategy 4: Write-Back Caching (Lazy Write)
Write-back caching, also known as lazy write or sometimes write-behind, flips the script by prioritizing write performance.
In this strategy, writes go to cache first, and the write is acknowledged as completed to the user, then the data is written to the database later (asynchronously).
How it Works
When a user updates data, the system updates the cache and quickly returns success, without immediately touching the database.
The new data sits in cache and may be written to the database under certain conditions: e.g. when that cache entry is evicted/replaced, or after a fixed interval, or when a batch of updates accumulate.
If another read comes for that data, it’s served from cache.
Eventually, the database is updated with the cached value.
Why Use Write-back
Speed and throughput.
Writes are very fast since they hit in-memory cache and return.
This is great for write-heavy workloads that need low latency.
It also can reduce the write load on the database by coalescing multiple updates.
Example
A collaborative document editor might buffer changes in cache for a while.
Every tiny edit keystroke doesn’t immediately hit the database.
Instead, it writes changes to cache and users see instant responsiveness.
The system then periodically or on certain triggers writes those changes to the DB.
Another example is analytics counters – you could count events in cache and write back totals to the database once a minute.
Pros
Very fast writes and high throughput, since memory cache is faster than disk or a remote DB and you’re not waiting on the DB for each operation.
It also can optimize database usage by batching writes.
Cons
Risk of data loss or inconsistency.
If the cache node crashes or is lost before it writes the data to the database, that data is gone.
Also, if someone bypasses the cache and reads from the database, they might get stale info until the cache flushes its writes.
Write-back requires additional logic to ensure data eventually reaches the DB and to reconcile state on failures. It’s more complex to implement correctly, especially in distributed systems.
When to Use Write-back
Use it when performance is paramount and occasional inconsistency is acceptable.
It’s suitable for write-intensive scenarios where the system can tolerate eventual consistency – for example, buffering user actions, analytics, or scenarios where losing the very latest writes isn’t catastrophic.
Due to the risk, many systems avoid pure write-back unless they have very reliable cache tiers or secondary measures.
If you mention write-back, also mention mitigation (like replication of the cache or a fallback) to show you understand the trade-off.
Choosing the Right Strategy (and Combining Them)
There’s no one-size-fits-all solution to cache invalidation – the best strategy depends on your data’s characteristics and what your application needs.
Often, you’ll combine strategies to get the best of both worlds.
For example, you might use write-through for critical data that must always be up-to-date, but also apply a TTL to cache entries as a fallback to auto-expire anything that somehow wasn’t updated.
Or use mostly cache-aside (lazy loading with TTL) for simplicity, and add write-through only for a few hot items that users immediately read after writing.
When choosing a strategy, consider:
Read vs Write Patterns: If reads greatly outnumber writes and data must be fresh, lean towards write-through. If writes are frequent and reads sporadic, write-around or write-back can be beneficial to avoid constant cache churn.
Data Freshness Requirements: For highly critical data (financial transactions, inventory stock levels), you want minimal stale data – write-through or even explicit cache invalidation on changes is key. For less critical or rapidly updating data (like a news feed), a short TTL might suffice.
Performance vs Consistency: Write-back gives max performance at the cost of consistency risk, write-through gives strong consistency at cost of performance. Decide what the priority is.
Cache Capacity: If your cache storage is limited, write-around helps by not filling it with every write. If cache space is plentiful, write-through’s extra entries aren’t as much of an issue.
In practice, caching layers often use TTL plus an appropriate write policy together.
Beyond these, there are other techniques like event-driven invalidation and versioned cache keys.
Those can achieve fine-grained consistency but add complexity.
For many cases, a solid TTL plus one of the above write strategies strikes a good balance.
Final Thoughts
Cache invalidation is notoriously hard, but it doesn’t have to be mystifying.
By using the strategies above, you can solve the cache consistency problem in a way that fits your app’s needs.
For beginners and those prepping for system design interviews, focus on explaining these trade-offs in simple terms: “I’ll use TTL to auto-expire cache entries and a write-through policy for the user profile data so it’s always updated, maybe combined with cache-aside for everything else.”
This shows you get both performance and consistency aspects.
Remember, caching is a tool to speed up systems – but freshness of data is key to correctness.
FAQs
Q1: What is cache invalidation and why is it important?
Cache invalidation is the process of removing or updating cached data when the original data changes. It’s crucial for maintaining consistency between the cache and the database. Without invalidation, users might be served stale data, seeing outdated information that doesn’t reflect the latest state. Effective invalidation strategies ensure your application returns fresh, accurate data while still benefiting from the speed of caching.
Q2: What is the difference between write-through, write-around, and write-back caching?
Write-through: On every data write, update the cache and database simultaneously. This keeps the cache up-to-date but makes writes slower.
Write-around: On data write, skip the cache – write only to the database. The cache is filled later when that data is read. This improves cache efficiency but means a recent write might not appear in cache until first read.
Write-back: On write, update the cache first and delay writing to the database. This makes writes very fast, but the risk is that if the cache fails before flushing to the DB, you could lose data.
Q3: What is TTL in caching, and when should I use it?
TTL (Time-to-Live) is an expiration time set on cache entries. It defines how long an item stays in the cache before it’s considered stale and automatically removed or refreshed. You should use TTLs on cache entries to ensure that even if you don’t manually invalidate something, it won’t live in the cache forever. TTL is especially useful when data changes at predictable intervals or when absolute real-time accuracy isn’t critical.


