intermediate

libuv basics

Understand libuv as the portable eventing layer behind file I/O, networking, timers, and the worker pool.

libuv is the C library Node uses for the event loop, timers, async file I/O, DNS, networking, and a fixed-size thread pool (default 4 threads, configurable via `UV_THREADPOOL_SIZE`).

| Work type | Typical handling | |-----------|------------------| | TCP/UDP sockets | OS readiness APIs (epoll/kqueue/IOCP) on main loop | | File system (sync-looking async APIs) | Thread pool | | DNS lookup (`dns.lookup`) | Thread pool | | Crypto (`pbkdf2`, some ciphers) | Thread pool | | `fs.readFile` / `fs.writeFile` | Thread pool |

The thread pool is a shared resource across the process. Heavy crypto or disk work in many concurrent requests can queue behind the pool limit even though JavaScript looks "non-blocking."

					// Blocks a pool thread until done — can delay unrelated fs/crypto work
const hash = await promisify(crypto.pbkdf2)(password, salt, 100000, 64, 'sha512');
				

On interviews: explain what libuv owns versus V8, why some "async" APIs still use threads, and when pool exhaustion becomes a bottleneck.

Common pitfalls: assuming all I/O is free on the main thread; setting `UV_THREADPOOL_SIZE` without measuring; confusing `dns.lookup` (thread pool) with `dns.resolve` (network, different path).

The trade-off is balancing simplicity, performance, safety, and operability — name which axis you optimized and what cost you accepted.

Checklist:

  • Name libuv responsibilities: loop, timers, networking, pool.
  • List APIs that use the thread pool.
  • Explain pool size as a concurrency cap.
  • Connect pool saturation to tail latency.