Cache Consistency Challenges and Update Strategies in Backend Systems

This article explains why caching is essential for high‑traffic services, describes the inherent consistency problems between Redis and MySQL, analyzes four cache‑update strategies with concrete concurrency scenarios, and provides practical recommendations such as using delete‑after‑update, delayed double‑delete, expiration, MQ, and binlog subscription to achieve eventual consistency.

Top Architect
Top Architect
Top Architect
Cache Consistency Challenges and Update Strategies in Backend Systems

In real‑world business scenarios, data such as orders, members, and payments are persisted in relational databases like MySQL for strong transactional guarantees, but the performance of a single MySQL instance often cannot meet high QPS requirements of large‑scale traffic.

Most read‑heavy workloads (e.g., popular product info, social media posts) benefit from caching, which trades space for time by storing frequently accessed data in faster storage such as Redis or local memory.

Cache Significance

Cache replaces slower database reads with fast memory reads, improving overall read performance.

Consistency Challenges After Introducing Cache

Data now exists simultaneously in Redis and MySQL. If Redis is not updated promptly after a database write, the two stores become inconsistent. The inconsistency window cannot be eliminated completely because there is no transaction spanning both systems.

Even though strong consistency is impossible, achieving eventual consistency with a very short inconsistency window (ideally <1 ms) is acceptable for most applications.

Cache Update Strategies

Four common strategies are discussed:

Update database then update cache.

Update database then delete cache.

Update cache then update database.

Update cache then delete cache.

Each strategy is examined with detailed concurrency examples.

Strategy 1 – Update Database → Update Cache

Typical read‑through logic:

data = queryDataRedis(key);
if (data == null) {
    data = queryDataMySQL(key); // cache miss, read from MySQL
    if (data != null) {
        updateRedis(key, data); // write‑through after DB read
    }
}

When a write occurs, the database is updated first, then the cache is refreshed. In write‑write concurrency, the order of cache updates can cause temporary inconsistency (e.g., DB values 100→99→98 while cache becomes 100→98→99).

Strategy 2 – Update Database → Delete Cache

Code example:

deleteRedis(key); // invalidate cache
updateMySQL(); // then update DB

This avoids stale cache reads after a DB failure, but in read‑write concurrency a race can still cause a stale read if a read occurs between DB update and cache deletion.

Strategy 3 – Update Cache → Update Database

Code example:

updateRedis(key, data); // update cache first
updateMySQL(); // then update DB

If the DB update fails, the cache holds incorrect data, making this strategy risky.

Strategy 4 – Update Cache → Delete Cache

Code example:

updateRedis(key, data); // write to cache
// later, after DB update
deleteRedis(key); // invalidate cache

This approach is generally discouraged because it can leave stale data in the cache.

Recommended Approach – Update Database → Delete Cache

Updating the database first and then deleting the cache yields the smallest inconsistency window (the time between DB commit and cache deletion, usually a few milliseconds). This strategy works well for read‑dominant workloads.

Additional Techniques for Stronger Guarantees

1. Cache Expiration : Set a TTL (e.g., 1 minute) so that even if cache invalidation fails, the stale entry will eventually disappear.

2. Message Queue (MQ) for Cache Invalidation :

updateMySQL();
sendMQMessageToDeleteCache(key);

MQ provides at‑least‑once delivery, allowing retries if Redis is temporarily unavailable.

3. Delayed Double Delete :

// after DB update
deleteRedis(key);
sleep(N); // N is a short delay
deleteRedis(key); // second delete to cover race reads

The delay N must be tuned; too short renders the second delete ineffective, too long increases the window where stale reads can occur.

4. Binlog Subscription : Listen to MySQL binlog (e.g., using Canal) to detect data changes and trigger cache updates centrally, avoiding scattered cache‑maintenance code.

Multi‑Cache Scenarios

When a single DB record maps to multiple cache keys, a typical update flow is:

updateMySQL(); // update DB record
deleteRedisKey1(); // invalidate homepage cache
updateRedisKey2(); // refresh top‑10 cache
deleteRedisKey3(); // invalidate daily top‑100 cache

Because each step can fail, using MQ or binlog‑driven processors to handle cache updates asynchronously improves reliability.

Summary of Strategies

Strategy

Concurrent Scenario

Potential Issue

Mitigation

Update DB → Update Cache

Write + Read

Brief read of stale value before cache refresh

Usually acceptable

Update DB → Update Cache

Write + Write

Cache update order differs from DB order, causing inconsistency

Distributed lock (heavy)

Update Cache → Update DB

No concurrency

DB update may fail after cache is updated

Use MQ confirmation

Update Cache → Update DB

Write + Write

Cache update order differs from DB order

Distributed lock (heavy)

Delete Cache → Update DB

Write + Read

Read may fetch stale data before DB update completes

Delayed double delete

Update DB → Delete Cache

Write + Read (cache hit)

Read may see old value between DB commit and cache deletion

Usually negligible

Overall, for most internet services the "update database then delete cache" strategy provides the best trade‑off between consistency and performance.

Final Recommendations

For read‑heavy, write‑light workloads, use "update DB → delete cache".

For read‑write balanced or write‑heavy scenarios, consider "update DB → update cache" with MQ or binlog support.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendConsistencystrategy
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.