Cache-Aside (Lazy Loading) Lab (Interactive)
Step reads and writes through Redis and PostgreSQL, then fire concurrent writes to expose the DEL-vs-SET race. Run the application-orchestrated lazy-loading loop: cache hits, miss-and-populate flows, and safe invalidation by eviction.
Cache-Aside Write & Invalidation Lab
Drive the lazy-loading loop and prove why writes must DELETE the key, never SET it.
Write Path Strategy
› user:42 cached at v1. Cache-Aside engine ready — try reads, writes, then the concurrent-write race.
How It Works Under the Hood
In Cache-Aside the application owns cache logic: check Redis first, on miss query the database, then populate with an explicit TTL. On writes, the safe sequence is commit to the database then DEL the key. Junior engineers instead SET the new value, which breaks under concurrency — if two writers commit v1 then v2 to the database but their cache updates land in reverse order, Redis stores stale v1 permanently. Eviction forces the next read to re-fetch committed truth, which is why delete beats update. The pattern is memory-efficient and degrades gracefully if Redis dies.
Core Architectural Principles
- Miss path: GET nil → SELECT → SET key value EX 3600 → serve fresh data.
- Write path: commit to database first, then DEL the cache key — never SET it.
- Concurrent writes can land cache SETs out of commit order, permanently corrupting the value.
Cache-Aside is your default answer for read-heavy web apps; say why: lazy population saves memory and the database is a built-in fallback if the cache cluster dies. Then volunteer the race-condition detail — always evict on write, never update, because concurrent cache writes can invert commit order. Mention TTLs as a safety net and cache warming to kill cold-start penalties.
Memory efficiency and resilience come at the cost of a three-hop miss penalty on first reads and app-managed invalidation logic.