learn deep. ship safe.Practice testsFollow ByteMunSubscribe
Node.js · Senior

Advanced Node.js Interview Questions

12 Node.js interview questions for senior and lead developers (5+ years): event-loop lag, worker threads versus cluster, memory leaks, graceful shutdown, idempotency, rate limiting and caching. Each answer explains why the other options are wrong.

CoversApi designCachingDatabasesEvent loopEventsGraceful shutdownLibuvMemoryNode.jsOperationsPaymentsPerformanceRate limitingScalingWorker threads

By Published Answers checked by Deepak

Take it as a timed test

  • 12 questions
  • 18 min
  • Pass mark 60%
  • Answers shown at the end
Start the timed test

No sign-up. Your answers and scores stay in this browser.

This pro paper has 12 Node.js questions for senior and lead developers with roughly 5+ years of experience. It covers event-loop lag, worker threads versus cluster, memory leaks, graceful shutdown, idempotency, rate limiting and caching. Ten questions are on this page with full explanations; the timed test also includes two questions that aren't shown here, so practise for understanding rather than memory.

How should you use this paper?

Answer each practice question before opening its explanation, and say your reasoning out loud the way you would in an interview. Then take the timed test: 18 minutes, a pass mark of 60%, with answers shown at the end. Your report breaks your score down by topic and difficulty, and you can retry only the questions you missed.

Practice questions with answers

Try each one before opening the answer. The explanation covers why the other options are wrong. The timed test also uses 2 questions that aren't shown here, so practise for understanding, not memory.

Q1Choose one answerhard

Response times spike under load and CPU is high on one core. How do you confirm the event loop is being blocked?

  1. Measure event-loop delay (perf_hooks.monitorEventLoopDelay) and profile with --cpu-prof to find the synchronous hot path
  2. Add more RAM to the server
  3. Switch every function to async
  4. Increase the HTTP timeout
Show answer and explanation

Answer: A. Measure event-loop delay (perf_hooks.monitorEventLoopDelay) and profile with --cpu-prof to find the synchronous hot path

Event-loop delay shows how late timers fire: if p99 delay climbs with latency, something synchronous is hogging the thread. A CPU profile (--cpu-prof, Chrome DevTools or clinic.js) shows which functions take the time, often JSON parsing of huge payloads, sync crypto or a heavy regex. Making functions async doesn't move CPU work off the thread.

Q2Choose one answerhard

What is the key difference between worker_threads and cluster?

  1. Workers are threads inside one process and can share memory; cluster runs separate processes, each with its own memory
  2. They are two names for the same thing
  3. Cluster is only for CPU work; workers only for HTTP
  4. Workers can't use npm packages
Show answer and explanation

Answer: A. Workers are threads inside one process and can share memory; cluster runs separate processes, each with its own memory

worker_threads run JavaScript in parallel within one process. They communicate by messages and can share memory through SharedArrayBuffer, which suits CPU-heavy jobs like image processing. cluster forks whole processes to spread incoming connections across cores. Workers are lighter to start; processes isolate crashes and memory better.

Q3Choose one answerhard

Memory in a long-running API climbs steadily until the process restarts. What's the usual culprit, and how do you find it?

  1. An unbounded in-memory cache or array that only grows; compare heap snapshots over time to see what is retained
  2. Too many console.log calls
  3. Using let instead of const
  4. The garbage collector is turned off by default
Show answer and explanation

Answer: A. An unbounded in-memory cache or array that only grows; compare heap snapshots over time to see what is retained

Classic leaks are a module-level Map used as a cache with no size limit or expiry, listeners added per request and never removed, and closures holding large objects. Take heap snapshots a few minutes apart under load and diff them: whatever keeps growing points to the code. Fix it with an LRU cache with a maximum size, or by removing listeners.

Q4Select all that applyhard

On SIGTERM during a deploy, what should a Node.js API do? Select all that apply.

  1. Stop accepting new connections with server.close()
  2. Let in-flight requests finish, with a time limit
  3. Close database pools and other connections
  4. Call process.exit(0) immediately
Show answer and explanation

Answer: A. Stop accepting new connections with server.close() + B. Let in-flight requests finish, with a time limit + C. Close database pools and other connections

A graceful shutdown stops taking new work, finishes what is running, releases resources, then exits. Calling process.exit(0) straight away cuts off in-flight requests and can leave transactions half-done. Add a hard timeout (say 10 to 30 seconds) so a stuck request can't block the deploy, and fail health checks first so the load balancer stops sending traffic.

Q5What does this code output?medium

What does prependListener change about the order listeners run in?

javascript
const { EventEmitter } = require('events');
const e = new EventEmitter();
e.on('x', () => console.log('a'));
e.prependListener('x', () => console.log('b'));
e.emit('x');
  1. b, then a
  2. a, then b
  3. Only b
  4. Only a
Show answer and explanation

Answer: A. b, then a

Listeners normally run synchronously in the order they were added. prependListener puts the new listener at the front of the list, so b runs before a. Also note that emit is synchronous: all listeners finish before emit returns, so a slow listener blocks whoever emitted the event.

Q6Choose one answerhard

A client retries a 'create payment' request after a timeout. How do you make sure the customer isn't charged twice?

  1. Require an idempotency key; store the result per key and return the same result for repeats
  2. Tell clients never to retry
  3. Use a GET request instead
  4. Add a longer timeout
Show answer and explanation

Answer: A. Require an idempotency key; store the result per key and return the same result for repeats

Timeouts don't tell the client whether the first request succeeded, so retries are unavoidable. With an idempotency key, the server records the first outcome under that key, ideally in the same transaction as the charge, and returns it for any repeat instead of acting again. Stripe and most payment APIs work this way. Keys usually expire after a day or so.

Q7Choose one answerhard

Why is a token bucket a popular rate-limiting algorithm?

  1. It allows short bursts up to the bucket size while keeping the average rate fixed
  2. It blocks every request after the first per second
  3. It needs no state at all
  4. It is the only algorithm that works with Redis
Show answer and explanation

Answer: A. It allows short bursts up to the bucket size while keeping the average rate fixed

Tokens refill at a steady rate up to a maximum, and each request spends one. Clients that were quiet can burst, which feels natural for real users, while the long-run rate stays capped. With several API instances, keep the bucket in a shared store such as Redis, using an atomic operation, so limits hold across servers.

Q8True or falsehard

UV_THREADPOOL_SIZE affects how many fs and crypto.pbkdf2 operations run in parallel.

TrueFalse

Show answer and explanation

Answer: True

True. libuv runs file system work, DNS lookups with dns.lookup, and some crypto and zlib calls on a thread pool with 4 threads by default. If you hash many passwords with pbkdf2 or scrypt, they queue behind each other. Raising UV_THREADPOOL_SIZE before startup helps, but network sockets don't use the pool at all.

Q9Match each item on the leftmedium

Match each caching layer to what it is best at.

  1. CDN
  2. Redis
  3. In-process LRU cache
  4. Cache-Control header
  • The fastest lookups, but separate in each instance
  • Serving static files and public pages from servers near the user
  • A shared cache that every API instance can read
  • Telling browsers and proxies how long to reuse a response
Show answer and explanation

Answer: CDN → Serving static files and public pages from servers near the userRedis → A shared cache that every API instance can readIn-process LRU cache → The fastest lookups, but separate in each instanceCache-Control header → Telling browsers and proxies how long to reuse a response

Layers stack. A CDN absorbs public traffic before it reaches you. Redis gives every instance the same view, such as sessions and computed results. An in-process LRU avoids even a network hop, but each instance holds its own copy and may be stale. Cache-Control controls reuse downstream. Most bugs come from invalidation, so decide expiry rules up front.

Q10Choose one answerhard

An endpoint returns 50 orders and runs 51 database queries. What is the problem and the usual fix?

  1. The N+1 query problem; fetch the related rows in one batched query or a join
  2. The database needs more RAM
  3. Too few indexes on the orders table
  4. JSON serialisation is slow
Show answer and explanation

Answer: A. The N+1 query problem; fetch the related rows in one batched query or a join

One query loads the list, then one more runs for each item to load its related data: N+1. Latency grows with the result size. Batch the lookups with a single WHERE id IN (...) or a join, use your ORM's eager loading, or a DataLoader in GraphQL. Logging the query count per request catches this early.

Answered them all? Take the same questions against the clock and get a topic-by-topic report.

Start the timed test

More Node.js quizzes

All Node.js quizzes →