Facebook Pixel

Node.js Performance and Scaling Interview Questions Clusters, Streams, and Memory

Master Node.js performance and scaling interview questions cluster module, streams, memory management, and handling high traffic.

Node.js Performance and Scaling Interview Questions

Performance and scaling are key topics in Node.js interviews. Here are the most common questions.

Q1: How Do You Scale a Node.js Application?

Answer:

  1. Cluster mode Run multiple instances on one server (one per CPU core)
  2. Load balancing Distribute traffic across multiple servers
  3. Caching Redis for frequently accessed data
  4. Database optimization Indexes, query optimization, connection pooling
  5. CDN Serve static assets from edge locations
  6. Microservices Split into smaller, independent services
// Cluster mode const cluster = require("cluster"); const os = require("os"); if (cluster.isPrimary) { const numCPUs = os.cpus().length; for (let i = 0; i < numCPUs; i++) { cluster.fork(); } } else { // Worker process start Express app require("./app"); }

Or use PM2: pm2 start app.js -i max

Q2: What Are Streams in Node.js?

Answer: Streams handle reading/writing data in chunks instead of loading everything into memory.

// Readable stream const readStream = fs.createReadStream("large-file.txt"); // Writable stream const writeStream = fs.createWriteStream("output.txt"); // Pipe read from one, write to another readStream.pipe(writeStream);

Types: Readable, Writable, Duplex (both), Transform (modify data).

Q3: What Is the Difference Between fs.readFile and fs.createReadStream?

Answer:

  • fs.readFile Reads entire file into memory. Bad for large files (OOM).
  • fs.createReadStream Reads in chunks. Memory-efficient for large files.
// BAD for large files fs.readFile("10gb-file.txt", (err, data) => { ... }); // OOM crash // GOOD for large files const stream = fs.createReadStream("10gb-file.txt"); stream.on("data", chunk => { ... }); // Process chunk by chunk

Q4: What Is Memory Leak and How Do You Detect It?

Answer: A memory leak occurs when memory is allocated but not released.

Detection:

// Monitor memory setInterval(() => { const used = process.memoryUsage(); console.log({ rss: `${Math.round(used.rss / 1024 / 1024)} MB`, heap: `${Math.round(used.heapUsed / 1024 / 1024)} MB` }); }, 10000);

Common causes:

  • Global variables accumulating data
  • Event listeners not removed
  • Closures holding references
  • Timers not cleared

Q5: How Do You Handle CPU-Intensive Tasks in Node.js?

Answer: Node.js is single-threaded CPU-intensive tasks block the event loop. Solutions:

// 1. Worker threads (for CPU-heavy work) const { Worker } = require("worker_threads"); const worker = new Worker("./heavy-task.js"); worker.on("message", result => console.log(result)); // 2. Child process (for external programs) const { fork } = require("child_process"); const child = fork("./heavy-task.js"); // 3. Offload to a queue (Bull, SQS) // 4. Use a separate microservice

Q6: What Is the Buffer in Node.js?

Answer: Buffer is a chunk of binary data (similar to an array of integers). Used for reading files, network data, and streams.

const buf = Buffer.from("Hello", "utf-8"); console.log(buf); // <Buffer 48 65 6c 6c 6f> console.log(buf.toString()); // Hello console.log(buf.length); // 5

Q7: How Do You Optimize Database Queries?

Answer:

  1. Indexes Create compound indexes for frequent queries
  2. Projection Select only needed fields
  3. Pagination Use skip/limit or cursor-based
  4. Lean queries Use .lean() for read-only (returns plain objects)
  5. Connection pooling Reuse database connections
  6. Caching Cache frequently accessed data in Redis
// Optimized query const users = await User.find({ active: true }) .select("firstName lastName email") // Projection .lean() // Plain JS objects, faster .limit(20) // Pagination .sort({ createdAt: -1 }); // Uses index

The Takeaway

Performance and scaling questions cover: cluster mode (multiple instances per CPU core), streams (process data in chunks, not all in memory), fs.readFile vs createReadStream (memory efficiency), memory leaks (monitor process.memoryUsage, common causes), CPU-intensive tasks (worker threads, child processes, queues), Buffers (binary data), and database optimization (indexes, projection, lean, pagination, caching).

Use cluster mode (multiple instances per CPU core via PM2 -i max or cluster module), load balancing (Nginx with multiple instances), caching (Redis for hot data), database optimization (indexes, query tuning), CDN for static assets, and microservices for independent scaling.

Streams process data in chunks instead of loading everything into memory. Types: Readable, Writable, Duplex, Transform. Use fs.createReadStream instead of fs.readFile for large files to avoid out-of-memory errors. Pipe connects readable to writable streams.

Use worker_threads for in-process CPU work, child_process (fork) for separate scripts, or offload to a queue (Bull, SQS) processed by separate workers. Never run CPU-heavy tasks in the main event loop they block all other requests.

Monitor process.memoryUsage() periodically. Common causes: global variables accumulating data, event listeners not removed (use EventEmitter.setMaxListeners and off()), closures holding references, and timers not cleared (clearInterval/clearTimeout). Use heap snapshots and Chrome DevTools for debugging.

Create compound indexes for frequent queries, use projection (.select('firstName lastName')), use .lean() for read-only queries (returns plain JS objects, faster), paginate with skip/limit or cursor, use connection pooling, and cache frequently accessed data in Redis.

Ready to master Node.js completely?

Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course to dive deeper with high-quality video tutorials, solve interview questions, and a premium community.

Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.