Cloud · Scale & Traffic · DWG NO. 038

Cache-Aside

Load data into cache on a miss and read from cache otherwise, keeping the cache and the data store loosely coupled.

TypeScale/Traffic
ScopeRead path
ComplexityLow
Common inWeb app data access, session data, expensive query results

Every read hitting the database directly doesn't scale

A product page read a thousand times a minute, backed by a query that takes 200ms, means the database does that same expensive work over and over for data that barely changes. Most of that load is pure waste.

Check the cache first, fall back to the source

The application checks the cache before reading. On a hit, it returns the cached value directly. On a miss, it reads from the real data store, populates the cache with that value, and returns it — so the next read for the same key is a cache hit.

App1. checkCache2. miss → readDatabase3. populate

A read-through cache-aside lookup

`getProduct` only ever queries the database when the cache doesn't already have an answer, and stores the result before returning.

cache-aside.js
const cache = new Map();

const database = {
  async query(id) {
    console.log(`database: expensive query for ${id}`);
    return { id, name: "Wireless Mouse", price: 29.99 };
  },
};

async function getProduct(id) {
  if (cache.has(id)) {
    console.log(`cache: hit for ${id}`);
    return cache.get(id);
  }
  const product = await database.query(id);
  cache.set(id, product);
  return product;
}

await getProduct("sku-1"); // database: expensive query
await getProduct("sku-1"); // cache: hit
await getProduct("sku-2"); // database: expensive query (different key)

Trade-offs