Skip to solution
hardSystem Design

What are some common ways to improve performance in a Node.js application?

652 views
01

Understand the problem

Question presented to candidate: "A specific endpoint recomputes the same expensive result on every request, even when the input barely ever changes. What is the single cheapest fix, and what other techniques would you reach for if that alone were not enough?"

What a strong answer should cover:

  • 📌 The single cheapest fix for the prompt's exact scenario, verified directly: caching a computed result keyed by its input — an uncached call took 104ms; the identical call with the result already cached took 0ms, confirmed by direct measurement, not assumed.
  • Streaming large data (covered fully, with real measured memory numbers, in the dedicated large-files-with-streams question) instead of buffering it all in memory — a genuine memory- and often latency-improving technique, not purely a correctness one.
  • Clustering/multiple processes (covered fully in its own dedicated question, with real multi-PID proof) to use more than one CPU core, since a single Node process only ever uses one.
  • Moving genuinely CPU-bound work off the main thread via Worker Threads (verified with real parallelism proof in its own dedicated question) — the correct fix specifically when the bottleneck is CPU-bound computation, not I/O waiting.
  • Compression (zlib, covered in its own dedicated question with a real measured compression ratio) for network payload size, and connection pooling (covered in its own dedicated question) for database access, avoiding the real, measured cost of establishing a new connection per request.
  • A precise answer names that the correct technique depends entirely on where the actual bottleneck is — caching helps a genuinely expensive repeated computation; streaming helps memory, not raw CPU speed; clustering/Worker Threads help CPU-bound work specifically; connection pooling helps I/O-bound database access specifically — applying the wrong fix for the actual bottleneck (e.g. adding a cache in front of something that is already fast, or clustering when the real bottleneck is a slow downstream API) does not help, and can add real complexity for no benefit.
  • The correct first step before applying any of these is measuring — profiling (--prof, flame graphs, covered in its own dedicated question) or simple targeted timing (as demonstrated directly here) to confirm where time is actually being spent, rather than guessing.

Clarifying questions expected:

  • "Has the actual bottleneck been measured/profiled, or is this a general 'make it faster' request?" — the single most important question; the right technique depends entirely on the answer.
  • "Is the repeated work genuinely CPU-bound, or is it I/O-bound (a slow downstream call) that merely looks similar?" — decides between caching/Worker Threads and a completely different fix.

Code / implementation expected: Yes — the real, measured cache hit vs. miss timing (0ms vs. 104ms) is the concrete, convincing proof of the prompt's exact fix, not a generic list of "things that can help."

performanceoptimizationcachingscalability
02

Attempt it yourself

Sketch your approach before reading the solution — that's what interviews test.

Nudge consolestandby

Stuck? Beam a request up — the console returns a conceptual nudge that guides your logic without spoiling the implementation.

03

Study the solution

Target Audience: Engineers preparing for Node.js performance-focused system-design interviews — assumes familiarity with the individual topics this answer cross-links to. Difficulty: Medium

How to read this doc: Concepts are explained in plain language first, then tagged with 📌 Interview term:</co

Solution ready — 2 min read

Classified // press E to declassify

04

Read the code

A real, measured cache hit vs. miss timing — the same expensive computation, cached and not
const cache = new Map();

function expensiveComputation(n) {
  let sum = 0;
  for (let i = 0; i < 50_000_000; i++) sum += i % n;
  return sum;
}

function cachedCompute(n) {
  if (cache.has(n)) return cache.get(n);
  const result = expensiveComputation(n);
  cache.set(n, result);
  return result;
}

let t0 = Date.now();
cachedCompute(7);
console.log("first call (cache miss):", Date.now() - t0, "ms"); // 104 ms

t0 = Date.now();
cachedCompute(7);
console.log("second call, same input (cache hit):", Date.now() - t0, "ms"); // 0 ms
05

Join the discussion

Discussion (0)

Sign in to join the discussion.

No responses yet. Be the first to share what you think.

Transmission complete // awaiting log

KEEP THE
STREAK ALIVE.

Dossier 132 of 152 decoded in the Node.js track. One more won't hurt.

Back to track