Fixing Silently Stale Reads When Using Redis as a Write-Through Cache
Redis has become one of the most widely used technologies for improving application performance.
It powers:
- Session storage
- API caching
- Shopping carts
- Rate limiting
- Leaderboards
- Feature flags
- Database caching
One of the safest caching strategies is often considered to be:
Write-Through Cache
The basic workflow appears simple:
Application
β
βΌ
Update Database
β
βΌ
Update Redis
β
βΌ
Return Success
Since every write also updates the cache, many developers assume:
Cache
=
Always Fresh
Unfortunately, production systems often tell a different story.
Users report problems such as:
- Recently updated profiles showing old information
- Shopping carts reverting to previous values
- Inventory counts appearing inconsistent
- API responses returning outdated records
- Dashboard metrics lagging behind database updates
Everything seems correct:
- Database contains the latest value.
- Redis contains the latest value.
- No errors appear in logs.
Yet some users still receive stale data.
This isn't usually a Redis bug.
It's often the result of subtle consistency issues in distributed systems.
This guide explains why stale reads occur even with write-through caching and how to eliminate them in production architectures.
What You Will Learn From This Article
After reading this guide, you'll understand:
- How write-through caching works.
- Why stale reads still happen.
- Replication lag effects.
- Race conditions during writes.
- Cache consistency strategies.
- Monitoring techniques.
- Production best practices.
What Is Write-Through Caching?
In a write-through cache:
Application
β
βΌ
Database Updated
β
βΌ
Cache Updated
The application updates both storage layers before reporting success.
This differs from:
- Cache-aside
- Write-back
- Write-behind
where cache synchronization happens differently.
Why Developers Choose Write-Through
Advantages include:
- Fresh cache entries
- Faster subsequent reads
- Predictable write flow
- Reduced cache misses
It appears to solve consistency problems automatically.
However:
Consistency
Is Hard
especially in distributed environments.
Understanding Stale Reads
A stale read occurs when an application retrieves:
Old Data
after:
New Data
has already been written.
Example:
Database
Name = Alice Smith
Cache
Name = Alice
Users continue seeing:
Alice
instead of:
Alice Smith
Common Cause #1
Redis Replication Lag
Many production deployments include:
Primary Redis
β
βΌ
Replica Redis
Write flow:
Application
β
Primary
Read flow:
Application
β
Replica
Replication takes time.
Even if only milliseconds,
clients may briefly read outdated values.
Solution
Critical reads immediately following writes should query:
Primary Redis
or bypass the cache entirely until replication completes.
Common Cause #2
Race Conditions
Imagine:
Request A:
Update Price
=
$50
Request B:
Update Price
=
$45
If updates complete in unexpected order:
Older Value
Overwrites
Newer Value
Cache becomes inconsistent.
Solution
Use:
- Version numbers
- Optimistic locking
- Atomic updates
- Compare-and-set operations
These prevent outdated writes from replacing newer data.
Common Cause #3
Partial Write Failures
Workflow:
Database Updated
β
Redis Update
β
Application:
Returns Success
Database is correct.
Cache is stale.
Solution
Treat database and cache updates as a single logical operation.
If cache synchronization fails:
- Retry immediately.
- Queue retry jobs.
- Invalidate the cache.
- Alert operators.
Never ignore failed cache writes.
Common Cause #4
Reading Before Cache Update Completes
Timeline:
Write Starts
β
Database Updated
β
Read Arrives
β
Cache Updated
The read accesses the previous cache value.
Milliseconds matter.
Solution
Synchronize write operations or temporarily invalidate the affected cache entry before updating it.
Common Cause #5
Multiple Application Instances
Architecture:
App A
App B
App C
Each instance writes independently.
Poor coordination increases consistency problems.
Distributed systems require shared synchronization strategies.
Cache Expiration Doesn't Solve Everything
Developers often assume:
TTL
=
Consistency
TTL only limits how long stale data survives.
It does not prevent stale reads immediately after an update.
Atomic Operations
Whenever possible, use Redis atomic commands.
Instead of:
GET
Modify
SET
consider:
- Transactions
- Lua scripts
- Atomic increment operations
These reduce race conditions.
Versioning Helps
Example object:
{
"id": 42,
"version": 8,
"name": "Alice"
}
Before overwriting:
Compare Version
Reject older versions.
This prevents stale cache updates.
Cache Invalidation
Sometimes the safest update is:
Delete Cache
instead of:
Overwrite Cache
Next read:
Cache Miss
β
Read Database
β
Repopulate Cache
Simple invalidation is often more reliable than complex synchronization.
Distributed Locks
For high-value updates:
Acquire Lock
β
Update
β
Release Lock
This reduces conflicting writes.
However:
locks should be used carefully to avoid reducing throughput.
Monitor Cache Consistency
Track:
- Cache hit ratio
- Replication lag
- Cache write failures
- Update latency
- Cache invalidations
Observability is essential.
Detect Silent Failures
Log:
Database Updated
Redis Failed
Do not silently continue.
Production systems should generate alerts whenever cache synchronization fails.
Real-World Example
An e-commerce platform updates:
Inventory
Workflow:
Database
β
Redis
β
Customer Reads
A Redis update occasionally fails due to a transient network issue.
The application ignores the failure.
Thousands of users continue seeing outdated inventory.
Products appear available when they are actually sold out.
The fix:
- Retry cache updates
- Invalidate failed cache entries
- Monitor synchronization failures
- Verify replication health
Inventory remains consistent.
Performance Considerations
Write-through caching improves read latency,
but every write now updates:
- Database
- Redis
This increases write latency slightly.
For read-heavy applications,
the trade-off is usually worthwhile.
Best Practices Checklist
When implementing write-through caching:
β Update database first
β Update Redis immediately afterward
β Handle cache update failures
β Monitor replication lag
β Use atomic Redis operations
β Version critical records
β Retry failed cache writes
β Log synchronization failures
β Test concurrent updates
β Monitor cache consistency metrics
Common Mistakes to Avoid
Avoid:
β Assuming write-through guarantees perfect consistency
β Ignoring Redis replication lag
β Swallowing cache update errors
β Updating cache before the database
β Using long TTLs as a consistency strategy
β Ignoring concurrent writes
β Failing to monitor cache synchronization
Why This Bug Is Difficult to Diagnose
Unlike application crashes,
stale reads often leave:
No Exceptions
Everything appears healthy:
- Database is correct.
- Redis is running.
- APIs return responses.
Yet users occasionally receive outdated information.
These intermittent failures make stale-read bugs particularly challenging to reproduce.
Understanding the timing and consistency guarantees of distributed systems is the key to identifying them.
Wrapping Summary
Write-through caching with Redis is an effective strategy for keeping frequently accessed data synchronized between the database and cache, but it is not a guarantee of perfect consistency. Replication lag, race conditions, partial write failures, concurrent updates, and improper cache synchronization can all result in stale reads that are difficult to detect because they often produce no visible errors.
Building a reliable write-through caching system requires more than simply updating Redis after every database write. Production-ready architectures should incorporate atomic operations, versioning, retry mechanisms, cache invalidation strategies, comprehensive monitoring, and robust error handling. Critical applications should also account for replication delays and ensure that consistency-sensitive reads use appropriate data sources.
By treating cache consistency as a distributed systems challenge rather than a simple performance optimization, developers can build Redis-backed applications that remain both fast and reliable as traffic and complexity grow.
π€ Share this article
Sign in to saveRelated Articles
Comments (0)
No comments yet. Be the first!