Redis Cache Aside for Product Details: A Frontend Dev's Guide to Backend Caching
Product detail pages are the most-read, least-changed surface in e-commerce, and a poorly designed cache can silently serve stale data to every anonymous user. This walkthrough shows how to treat Redis as a disposable acceleration layer with explicit state handling, fail-open degradation, and self-healing—patterns that apply to any read-heavy API.
The `fullstack-mall` project adds a Redis Cache Aside layer to its public product detail endpoint to stop read-heavy traffic from hammering MySQL. The implementation models explicit cache states—HIT, MISS, NULL_HIT, DEGRADED, and BYPASS—so the business layer never guesses what a null return means. Null values for non-existent products are cached with a short TTL to prevent cache penetration, and any Redis failure triggers a fail-open degradation that falls back to the database instead of throwing a 500 error.
On the write side, product creation, status changes, and subtitle updates all delete the relevant cache key after a successful MySQL commit, rather than trying to update the cached JSON in place. This avoids field-assembly bugs and keeps the cache a discardable performance layer, not a second source of truth. Bad JSON in Redis is detected and deleted automatically, letting the next read self-heal by rebuilding from MySQL.
The article maps every backend concept to a frontend analogue—React Query cache, stale time, query keys—and provides curl commands, Redis CLI checks, and test strategies to verify the full MISS → PUT → HIT → EVICT → MISS lifecycle.
Explicit cache-state modeling is undervalued. Most systems collapse MISS, error, and disabled-cache into a single null, forcing callers to guess the system's health. A small enum eliminates that ambiguity.
The decision to delete rather than update the cache on writes is a deliberate trade-off: it accepts one extra database read on the next request in exchange for never assembling a broken or partial cached response from multiple write paths.
Self-healing from bad JSON is a cheap, high-leverage pattern. A single corrupted key can poison every subsequent request; deleting it on detection turns a persistent failure into a one-time blip.
TTL asymmetry between real values and null markers is a practical detail that many tutorials skip. A null TTL that's too long blocks newly created resources; one that's too short fails to prevent penetration.
Fail-open for a read cache is the correct default for most product-detail use cases. The database is the source of truth; a slower response is always better than a hard failure.