From 449549bc4fa642745291e5011fe52b876453eff8 Mon Sep 17 00:00:00 2001 From: Sam Roberts Date: Wed, 23 Aug 2017 14:59:06 -0700 Subject: [PATCH] doc: threadpool size, and APIs using the pool Not knowing which APIs use libuv's threadpool can lead to surprising performance problems. Document the APIs, and also document UV_THREADPOOL_SIZE, which can be used to fix problems. PR-URL: https://github.com/nodejs/node/pull/14995 Reviewed-By: Brian White Reviewed-By: James M Snell --- doc/api/cli.md | 25 +++++++++++++++++++++++++ doc/api/crypto.md | 13 +++++++++++++ doc/api/dns.md | 22 +++++++++++++--------- doc/api/fs.md | 8 ++++++++ doc/api/zlib.md | 7 +++++++ 5 files changed, 66 insertions(+), 9 deletions(-) diff --git a/doc/api/cli.md b/doc/api/cli.md index edfacd94c829e6..fae7de7b7a6f2e 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -568,6 +568,30 @@ appended to if it does. If an error occurs while attempting to write the warning to the file, the warning will be written to stderr instead. This is equivalent to using the `--redirect-warnings=file` command-line flag. +### `UV_THREADPOOL_SIZE=size` + +Set the number of threads used in libuv's threadpool to `size` threads. + +Asynchronous system APIs are used by Node.js whenever possible, but where they +do not exist, libuv's threadpool is used to create asynchronous node APIs based +on synchronous system APIs. Node.js APIs that use the threadpool are: + +- all `fs` APIs, other than the file watcher APIs and those that are explicitly + synchronous +- `crypto.pbkdf2()` +- `crypto.randomBytes()`, unless it is used without a callback +- `crypto.randomFill()` +- `dns.lookup()` +- all `zlib` APIs, other than those that are explicitly synchronous + +Because libuv's threadpool has a fixed size, it means that if for whatever +reason any of these APIs takes a long time, other (seemingly unrelated) APIs +that run in libuv's threadpool will experience degraded performance. In order to +mitigate this issue, one potential solution is to increase the size of libuv's +threadpool by setting the `'UV_THREADPOOL_SIZE'` environment variable to a value +greater than `4` (its current default value). For more information, see the +[libuv threadpool documentation][]. + [`--openssl-config`]: #cli_openssl_config_file [Buffer]: buffer.html#buffer_buffer [Chrome Debugging Protocol]: https://chromedevtools.github.io/debugger-protocol-viewer @@ -575,3 +599,4 @@ equivalent to using the `--redirect-warnings=file` command-line flag. [SlowBuffer]: buffer.html#buffer_class_slowbuffer [debugger]: debugger.html [emit_warning]: process.html#process_process_emitwarning_warning_type_code_ctor +[libuv threadpool documentation]: http://docs.libuv.org/en/latest/threadpool.html diff --git a/doc/api/crypto.md b/doc/api/crypto.md index 5ae5c28851df07..6c83aeaff8353d 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -1555,6 +1555,10 @@ crypto.pbkdf2('secret', 'salt', 100000, 512, 'sha512', (err, derivedKey) => { An array of supported digest functions can be retrieved using [`crypto.getHashes()`][]. +Note that this API uses libuv's threadpool, which can have surprising and +negative performance implications for some applications, see the +[`UV_THREADPOOL_SIZE`][] documentation for more information. + ### crypto.pbkdf2Sync(password, salt, iterations, keylen, digest)