Node.js path · Node's loop · Topic 6 of 8

The libuv thread pool

Not started

JavaScript in Node runs on one thread, but Node itself is not single-threaded. Network sockets are watched by the operating system (epoll, kqueue, IOCP) with no extra threads. Work that has no non-blocking OS interface, such as most file system calls, dns.lookup, some crypto (pbkdf2, scrypt, randomBytes with a callback) and zlib's asynchronous methods, is handed to libuv's thread pool, which has 4 threads by default.

Why it matters: Four busy threads can make unrelated file reads, DNS lookups and password hashes wait for each other.

1

How it works

The explanation, with examples you can run.

Seeing the queue

Six expensive hashes, four threads: the first four finish together, the last two have to wait for a free thread.

// pool.mjs (run with: node pool.mjs, then UV_THREADPOOL_SIZE=6 node pool.mjs)import { pbkdf2 } from "node:crypto" const start = performance.now()for (let i = 1; i <= 6; i++) {  pbkdf2("secret", "salt", 500_000, 64, "sha512", () => {    console.log(`hash ${i} done after ${Math.round(performance.now() - start)} ms`)  })}

With the default pool you will see two groups of finish times; with six threads (on a machine with at least six cores) they finish together.

Things to know

  • The pool is shared by everything in the process. A burst of slow dns.lookup calls (which every http.get("https://name...") does unless you pass an IP) can delay unrelated file reads.
  • The ...Sync functions (readFileSync, pbkdf2Sync) don't use the pool at all: they block the main thread, which is fine at start-up and harmful inside a request handler.
  • A bigger pool helps when work waits on disk or the OS; for CPU-heavy JavaScript of your own, the pool can't help, but worker threads can.
2

Check yourself

3 questions. Get them all right to finish this topic.

  1. 1.Which of these uses the libuv thread pool?
  2. 2.How many threads does the pool have by default?
  3. 3.Slow dns.lookup calls have filled the pool. What else slows down?

0 of 3 right so far. Get all three to finish this topic.