How does Node.js handle thousands of connections on one thread?
This tests non-blocking I/O: Node.js runs one thread for an event loop while the OS handles sockets via epoll or IOCP, resuming callbacks when data arrives. Mention the thread pool for DNS and fs work. A red flag is claiming threads spawn per request.
WHAT THIS TESTS: The interviewer wants to know if you understand the difference between concurrency and parallelism in Node.js. Specifically, they are checking whether you know that JavaScript runs on a single thread but I/O is offloaded to the operating system, allowing one process to manage many connections without creating a thread per request. They also want to see if you know the boundaries of the event loop, including what happens with CPU-intensive tasks and blocking operations.
A GOOD ANSWER COVERS: First, clarify that Node.js uses a single thread for JavaScript execution driven by an event loop, but the underlying libuv library and OS kernel handle asynchronous I/O. Second, explain that for network sockets, the OS uses event notification systems like epoll on Linux, kqueue on macOS, and IOCP on Windows to watch many connections at once; when data arrives, the event loop picks up the callback. Third, mention that not everything is non-blocking in the kernel, so DNS lookups and some file system operations use a small internal thread pool to avoid blocking the loop. Fourth, contrast this with a traditional thread-per-request model like Apache prefork, noting that Node avoids context switching overhead and memory bloat per connection.
COMMON WRONG ANSWERS: A major red flag is saying the event loop is literally a while loop that constantly polls every file descriptor in a busy wait. Another is claiming that Node spawns a new thread for each incoming connection, confusing it with Java servlets or Apache worker models. Some candidates say the event loop handles DNS and file reads directly without mentioning the thread pool, which shows shallow knowledge. Saying that single-threading means only one connection can be processed at a time is also incorrect and misses the non-blocking I/O concept entirely.
LIKELY FOLLOW-UPS: The interviewer may ask what happens if you run a heavy CPU calculation inside a request handler. They might ask how cluster mode or worker_threads relate to the event loop. You could also be asked to describe the phases of the event loop, such as timers, pending callbacks, idle, poll, check, and close callbacks, or to explain how setImmediate differs from setTimeout. Another common follow-up is asking how backpressure is managed in streams when the event loop is busy.
ONE CONCRETE EXAMPLE: Imagine an Express server handling ten thousand persistent WebSocket connections. Each socket is idle most of the time. In a thread-per-request model, the OS would need ten thousand threads sitting in memory, consuming roughly a few megabytes each. In Node.js, the process keeps one thread running JavaScript. The OS kernel tracks all ten thousand sockets. When one client sends a message, the kernel notifies Node via the event loop, the callback executes, and the thread moves on. If the server needs to read a local config file for each message, libuv dispatches that file read to its thread pool so the loop stays unblocked for the other 9,999 connections.
Read the original → nodejs.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.