AceDevHub
Advanced Node.js Interview QuestionsAdvancedConcept

Node.js · Question 74

How do you handle CPU-intensive tasks in Node.js?

Direct answer

Never run long synchronous CPU work on the main thread — offload to worker_threads, child processes, or a job queue (BullMQ worker); split work into chunks with setImmediate for minor tasks; scale horizontally for sustained CPU load.

The event loop is single-threaded — a 2-second JSON.stringify loop blocks all HTTP responses, health checks, and WebSocket pings until it finishes.

ApproachWhen
worker_threadsCPU-bound JS in same app — hashing, parsing
child_processIsolated/untrusted code, native CLIs
BullMQ workerAsync jobs off API hot path — apps/worker
setImmediate chunkingYield during long sync loops — last resort
Horizontal scaleMore containers, not bigger sync blocks
  • Anti-pattern — bcrypt.sync, heavy regex on megabyte strings in route handler.
  • libuv thread pool — fs/crypto DNS use threads but still limited pool (Q8).
  • Measure — event loop delay (perf_hooks, clinic.js) spikes when CPU blocked.
cpu-offload.mjs
import { Worker } from "node:worker_threads";

async function hashPassword(password) {
  return new Promise((resolve, reject) => {
    const w = new Worker("./bcrypt-worker.mjs", { workerData: { password } });
    w.on("message", resolve);
    w.on("error", reject);
  });
}

// Or enqueue: await emailQueue.add("send-cert", { userId });