← Academy

Cache-Aside Pattern

Accelerating data retrieval with Redis and Postgres

Here's what each node in the simulator represents:

💻 Client

Sends 3 GET requests — each asking for a different user record by key:

- Request 1 → key: rohan (exists in Redis)

- Request 2 → key: john (exists in Redis)

- Request 3 → key: doe (not in Redis, but exists in Postgres)

🖥️ Server

Acts as the application logic layer. It receives requests from the client and decides: *"Should I check cache first, or go straight to the database?"* In the Cache-Aside Pattern, the server always checks Redis first.

💾 Redis Cache

An in-memory key-value store — blazing fast (~1ms latency). It stores frequently accessed data in RAM. Think of it as your app's short-term Cache memory. See details under Redis.

🗄️ Postgres Database

A disk-based SQL database — reliable but slower than Redis (~10–100ms latency). It's the source of truth where all records live permanently. See details under PostgreSQL.


Flow overview: Client → Server → Redis (or → Postgres on cache miss)

Reading from a SQL database on every single request is *slow* — it involves disk I/O, query parsing, and network round trips. Under heavy load, this becomes a bottleneck.

The Solution: Cache-Aside Pattern

Instead of always going to Postgres, we put a Redis cache in front of it:

1. Request arrives → Server checks Redis first
2. CACHE HIT  → Data found in Redis → Return instantly (fast! ~1ms)
3. CACHE MISS → Data not in Redis → Query Postgres
               → Get the data → Save it to Redis → Return to client

On the first request for a key (cache miss), we pay the cost of a Postgres query. On every subsequent request for that same key (cache hit), we skip Postgres entirely. See TTL configuration for expirations.

Real-World Impact

A popular blog post queried by 10,000 users? With caching, only the first request hits Postgres. The other 9,999 get served from Redis at millisecond speed.

Press Play to see this unfold — watch which paths the purple packets take.

Let's look at what happens with each of the 3 requests in the simulation:

Request 1 — key: `rohan` → **Cache HIT** ✅

- Server asks Redis: "Do you have rohan?"

- Redis says: YES → returns "cached data for rohan"

- Server sends response to client. Postgres is never touched.

Request 2 — key: `john` → **Cache HIT** ✅

- Same flow as above. Redis has john → fast return.

Request 3 — key: `doe` → **Cache MISS** ⚠️

- Server asks Redis: "Do you have doe?"

- Redis says: NO (cache miss)

- Server queries Postgres: "Find doe in the users table"

- Postgres returns "db data for doe"

- Server saves `doe` to Redis (so next time it's a cache hit!)

- Server returns response to client

Watch the packet paths — a cache miss shows 2 hops (→ Redis → Postgres), while a hit shows just 1.


Interactive Checkpoints

▶ Empty Redis Cache (Force All Misses)

Apply

Click to clear all cached data from Redis. Now all 3 requests will miss the cache and fall back to Postgres. Watch the longer packet paths.

▶ Pre-seed Cache (Force All Hits)

Apply

Click to pre-fill Redis with rohan, john, and doe. All 3 requests will be cache hits — notice how packets never reach Postgres.

Now that you understand cache-aside, build it yourself:

🛠️ Step-by-Step in the Sandbox

  • Open the Interactive Sandbox in a new tab (link below).
  • Add a Client node — configure it with a GET request, key: myuser.
  • Add a Server node — connect Client → Server.
  • Add a Redis Cache node — connect Server → Redis.
  • Add a Postgres Database node — connect Server → Postgres.
  • In the Redis inspector, add a key: myuser with a value.
  • Click the Client node to simulate. Watch it hit Redis first!
  • Now remove that key from Redis and re-simulate — watch it fall back to Postgres.
  • That's the Cache-Aside pattern — fully in your control!

    🛠️

    Now Try It Yourself!

    Head to the Interactive Sandbox and build this architecture from scratch — drag, drop, connect, and simulate.

    Open Interactive Sandbox

    Opens in a new tab

    Running1/0

    No frames available