A Dockerized e-commerce API demonstrating a production-safe cache invalidation strategy using Redis versioned cache keys to prevent stale product inventory.
Executive Summary: Solving Stale Inventory with Deterministic Cache Invalidation
In distributed e-commerce systems, performance optimization often relies on aggressive caching. However, improperly designed cache strategies can introduce correctness issues — particularly when cache keys fail to reflect state changes.
In this project, the root cause of stale inventory data was a cache key design that relied solely on TTL expiration.
This project shows how to solve a common real-world problem:
Product pages displaying outdated inventory after stock updates.
•Root cause: cache key didn’t incorporate inventory changes; TTL-only caching served stale product detail payloads.
•Fix: versioned keys; write path increments product version; read path uses versioned key → stale cache cannot be returned.
•Zero downtime strategy: stateless API, external state in DB/Redis, healthcheck endpoint supports rolling updates in orchestrators (ECS/K8s); can scale horizontally without cache correctness issues.
•Optional: actively delete old key too (cleanup), but not required for correctness.
The main Problem in many e-commerce systems is that product details are cached for performance.
However, when inventory changes, cached responses may continue to serve stale data until TTL expires.
ShopNow — Stale product inventory due to caching
Issue: Product details page shows incorrect inventory after stock updates.
Root cause: Cache keys don’t change when inventory changes (TTL-only caching), so reads can return stale cached entries.
Fix: Versioned cache keys (or event-driven invalidation). On inventory update, increment version so the read path automatically uses a new key.
Key Takeaway
Cache invalidation is often considered one of the hardest problems in distributed systems. This project demonstrates that by shifting from time-based expiration to state-driven versioning, we can achieve deterministic freshness without sacrificing performance.
Correctness should not depend on TTL expiration.
With versioned keys, stale data becomes structurally impossible.
I have the full code and solution on my github if you will like to see how this staleness problem is solved using containerization.
https://github.com/GeorgyGold/shopnow/tree/ijbranch
Author:
Victory
Top comments (1)
Versioned cache keys are a solid approach to the stale data problem. The tradeoff I've run into is orphaned keys accumulating over time — old versions that never get explicitly evicted can build up surprisingly fast in high-write scenarios. Setting a conservative TTL on versioned keys as a safety net helps, even if the version-based invalidation is working correctly. Did you run into any memory pressure issues with key accumulation at scale?