DevPath · Learn to code ESPTEN

Testing and advanced Node

Performance and scaling

Cache: don't recompute what you already know

If an operation is expensive (a heavy query, an external call) and its result changes little, cache it. An in-memory store like Redis keeps key-value pairs with near-instant access and an optional TTL (time to live):

// Conceptual pseudocode:
let data = await redis.get("user:1");
if (!data) {                       // "miss": it was not in the cache
  data = await db.findUser(1);
  await redis.set("user:1", data, "EX", 60); // expires in 60 s
}

The cache-aside pattern: check the cache first; if there is a hit, return it; if there is a miss, compute, store in the cache and return.

Use all the cores

A Node process uses one core for your JS. To take advantage of a machine with several cores there are two complementary tools:

Don't block the event loop

Since your JS is single-threaded, a long synchronous operation freezes EVERYTHING: while it computes, no other request is served.

// BAD: blocks the event loop during the whole loop.
function slowSum(n) {
  let total = 0;
  for (let i = 0; i < n; i++) total += i; // if n is huge, nobody else advances
  return total;
}

The golden rule: keep the main thread free. Heavy CPU work goes to a worker_thread; I/O (network, disk, DB) is already asynchronous and does not block. That way the event loop keeps accepting and responding to requests.

Examples

Cache-aside: a hit avoids recomputing

const cache = new Map();

function getExpensive(key, compute) {
  if (cache.has(key)) return cache.get(key); // hit
  const value = compute();                    // miss: compute
  cache.set(key, value);                      // and store
  return value;
}

let times = 0;
const calc = () => { times++; return 42; };
getExpensive("x", calc);
getExpensive("x", calc); // second time: hit, does not recompute
console.log(times); // 1
Put this into practice

DevPath is a hands-on course: you read the theory here; in the app you put it into practice with exercises that really run, offline.

Start free in the app →
← Advanced asynchrony and streamsView the module →