Course contentsShow
← Node.js
Lesson 1310 of 1,98012. Caching Strategies and Application SpeedFree lesson

TTL-Based Expiration Strategies

You will build a mechanism to automatically prune stale data based on time-to-live intervals.

In this lesson, you will learn how to implement an automated pruning mechanism to discard stale data from your in-memory caches using Time-To-Live (TTL) expiration.

The Problem of Stale Data

When we store temporary data (like session tokens or transient job results) in memory to improve performance, our memory footprint grows indefinitely if we don't have a cleanup strategy. A TTL-based strategy assigns each record a "death date," ensuring that we only pay the memory cost for data that is currently relevant.

Implementing TTL Pruning

The most efficient way to handle this in Node.js is to store your data alongside a timestamp. You then execute a periodic "reaper" function—a background task—that scans the storage and deletes expired keys.

Consider this simplified implementation using a Map:

const cache = new Map();
const TTL = 60000; // 60 seconds

function set(key, value) {
  cache.set(key, { value, expiresAt: Date.now() + TTL });
}

// The "Reaper" function
setInterval(() => {
  const now = Date.now();
  for (const [key, entry] of cache.entries()) {
    if (now > entry.expiresAt) {
      cache.delete(key);
    }
  }
}, 30000); // Runs every 30 seconds

Why This Matters

If you don't prune your data, your Node.js process will eventually hit its --max-old-space-size limit, leading to frequent Garbage Collection pauses and, eventually, an OutOfMemory crash.

When designing your reaper, be mindful of the interval. If the interval is too short, you waste CPU cycles iterating over a large map; if it is too long, your memory usage remains unnecessarily high. A common strategy is to trigger the cleanup process only when a certain threshold of memory usage is reached, or to use a setTimeout on individual items if the dataset is small and precision is critical. By automating this, you keep your memory overhead predictable and your application speed consistent.

Key Takeaway: TTL expiration preserves application health by balancing the performance benefits of in-memory caching with the structural necessity of memory reclamation.