Skip to content
Caching

Lesson 12 of 14 · 22 min

x
12/14

Lesson position in the course — not completion. Use Mark Complete to track finished lessons (saved in this browser).

Multi-Level Caching & Cache Warming

Production systems rarely use a single cache layer. Multi-level caching stacks an L1 in-process cache (microseconds) in front of an L2 distributed cache like Redis (milliseconds) in front of the database (tens of milliseconds). Each level catches what the one below misses.

Cache warming preloads the cache before traffic arrives — critical after a deploy, cache flush, or cold start. A warming script loads the top 1000 products, popular articles, or configuration into Redis before flipping traffic. Without warming, the first wave of users after a deploy experiences a storm of cache misses.

Database-level caching is often overlooked. PostgreSQL's shared_buffers (buffer pool) caches table pages in RAM. MySQL's InnoDB buffer pool does the same. ORM-level second-level caches (Hibernate, EF Core) cache entity objects in-process. These are automatic — but tuning shared_buffers and understanding when the buffer pool is thrashing is part of cache performance engineering.

Before
Cold start — every request is a cache miss
1// After deploy or redis FLUSHALL2// First 10,000 users all hit the database3app.get('/products/featured', async (req, res) => {4  const products = await db.query(5    'SELECT * FROM products WHERE featured = true'6  );7  res.json(products);8});
After
Cache warming on startup
1// Warm cache before accepting traffic2async function warmCache() {3  const featured = await db.query(4    'SELECT * FROM products WHERE featured = true'5  );6  await redis.setex('products:featured', 3600, JSON.stringify(featured));7 8  const topIds = await db.query(9    'SELECT id FROM products ORDER BY views DESC LIMIT 1000'10  );11  for (const { id } of topIds) {12    const product = await db.query('SELECT * FROM products WHERE id = $1', [id]);13    await redis.setex(`product:${id}`, 3600, JSON.stringify(product));14  }15  console.log('Cache warmed with', topIds.length, 'products');16}17 18await warmCache();19// Now start the server

Check your understanding

  • What is L1 vs L2 here?Show answer

    Answer

    L1: in-process (fastest, per instance). L2: shared Redis/Memcached across instances.
  • Why warm caches after deploy?Show answer

    Answer

    Avoid a miss storm when every instance starts empty and stampedes the database.
  • Name a DB-level cache to be aware of.Show answer

    Answer

    PostgreSQL shared_buffers / InnoDB buffer pool — pages cached in engine memory.
Previous

Progress is saved in this browser.

Next Lesson