🌐 Detecting your location…
📢 Advertisement — Configure AdSense in Appearance → Customize → AdSense Settings

Node.js Interview Questions 2026: Event Loop, Streams and Scaling

⏱️4 min read  ·  807 words

Node.js interview questions test your understanding of the event loop, asynchronous patterns, streams, performance, and production deployment. This guide covers the most commonly asked Node.js questions for backend developer interviews in 2026.

Core Node.js Questions

1. Explain the Node.js event loop

Node.js Event Loop Phases (in order):
1. timers       — setTimeout, setInterval callbacks
2. pending I/O  — I/O errors from previous iteration
3. idle/prepare — internal use
4. poll         — retrieve new I/O events (MAIN PHASE)
5. check        — setImmediate callbacks
6. close        — close event callbacks (socket.destroy, etc.)

Microtask queue (runs BETWEEN each phase):
  - process.nextTick() — higher priority than Promises
  - Promise callbacks (.then/.catch)

Order of execution:
  1. Synchronous code
  2. process.nextTick() queue
  3. Promise callbacks
  4. setImmediate (check phase)
  5. setTimeout (timers phase, even setTimeout(fn, 0))

// Demonstrate event loop order
console.log('1 - sync');

setTimeout(() => console.log('2 - setTimeout'), 0);

setImmediate(() => console.log('3 - setImmediate'));

Promise.resolve().then(() => console.log('4 - Promise'));

process.nextTick(() => console.log('5 - nextTick'));

console.log('6 - sync');

// Output: 1, 6, 5, 4, 3, 2
// sync → nextTick → Promise → setImmediate → setTimeout

2. What is libuv and what does it do?

libuv is the C library that powers Node.js’s event loop and I/O operations:

  • Thread pool: Handles blocking operations (file I/O, crypto, DNS) on background threads
  • Event loop: Manages async callbacks
  • Platform abstraction: Works on Linux (epoll), macOS (kqueue), Windows (IOCP)

Default thread pool size: 4 workers. Can increase with UV_THREADPOOL_SIZE=8.

3. What are Node.js streams and when do you use them?

const fs = require('fs');
const zlib = require('zlib');
const { pipeline } = require('stream/promises');

// Streams: process data piece by piece, not all at once
// Memory efficient for large files

// Four types:
// Readable: fs.createReadStream, http.IncomingMessage
// Writable: fs.createWriteStream, http.ServerResponse
// Duplex:   net.Socket (both read and write)
// Transform: zlib.gzip (modifies data as it passes through)

// Good: streams don't load entire file into memory
async function compressFile(input, output) {
  await pipeline(
    fs.createReadStream(input),
    zlib.createGzip(),
    fs.createWriteStream(output)
  );
}

// BAD: loads entire file into memory
// const data = fs.readFileSync('huge-file.csv');  // could be 10GB!

// Streams for HTTP
const http = require('http');
http.createServer((req, res) => {
  const stream = fs.createReadStream('large-file.mp4');
  stream.pipe(res);  // efficient streaming to browser
}).listen(3000);

4. How do you handle errors in async Node.js code?

// 1. async/await with try/catch (most common in 2026)
async function getUser(id) {
  try {
    const user = await db.findUser(id);
    if (!user) throw new Error('User not found');
    return user;
  } catch (error) {
    logger.error({ error, id }, 'Failed to get user');
    throw error; // re-throw or return error response
  }
}

// 2. Express error handling middleware
app.get('/users/:id', async (req, res, next) => {
  try {
    const user = await getUser(req.params.id);
    res.json(user);
  } catch (error) {
    next(error); // pass to error handler
  }
});

app.use((error, req, res, next) => {
  logger.error(error);
  res.status(error.status || 500).json({ error: error.message });
});

// 3. Uncaught exceptions (last resort)
process.on('uncaughtException', (error) => {
  logger.error('Uncaught exception:', error);
  process.exit(1); // restart via PM2/supervisor
});

process.on('unhandledRejection', (reason, promise) => {
  logger.error('Unhandled rejection:', reason);
  // In Node.js 16+, this terminates the process
});

5. Explain worker threads in Node.js

const { Worker, isMainThread, parentPort, workerData } = require('worker_threads');

// Main thread
if (isMainThread) {
  // CPU-intensive work → offload to worker thread
  const worker = new Worker(__filename, {
    workerData: { data: largeDataArray }
  });

  worker.on('message', (result) => {
    console.log('Result:', result);
  });

  worker.on('error', (error) => {
    console.error('Worker error:', error);
  });
} else {
  // Worker thread
  const { data } = workerData;
  const result = expensiveComputation(data);  // doesn't block main thread!
  parentPort.postMessage(result);
}

// Use worker threads for:
// - CPU-intensive computation (image processing, crypto, compression)
// - Parallel data processing
// NOT needed for I/O operations (event loop handles those efficiently)

6. How do you scale a Node.js application?

// 1. Cluster module (use all CPU cores)
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();
  }
  cluster.on('exit', (worker) => {
    console.log(`Worker ${worker.id} died. Restarting...`);
    cluster.fork(); // auto-restart
  });
} else {
  require('./server'); // each worker runs the server
}

// 2. PM2 (recommended for production)
// pm2 start app.js -i max  # cluster mode, max workers
// pm2 start app.js -i 4    # 4 workers
// pm2 monit                # monitoring

// 3. Horizontal scaling
// Run multiple Node.js instances
// Load balance with nginx or AWS ALB

Node.js interview success: understand the event loop deeply (phases, microtasks vs macrotasks), know when to use streams for memory efficiency, explain worker threads vs cluster for scaling, and demonstrate async error handling. Advanced questions cover performance profiling (–prof, clinic.js), memory leaks detection, and production patterns.

✍️ Leave a Comment

Your email address will not be published. Required fields are marked *

🌐 Read in:🇬🇧 English🇩🇪 Deutsch🇧🇷 Português🇸🇦 العربية🇮🇳 हिन्दी🇧🇩 বাংলা