Commit | Line | Data |
---|---|---|
a47027a0 JB |
1 | # General guidelines |
2 | ||
3 | Performance is one of the main target of these worker pool implementations, poolifier team wants to have a strong focus on this. | |
d02a42b2 | 4 | Poolifier already has [benchmarks](./../benchmarks/README.md) where you can find some comparisons. |
a47027a0 JB |
5 | |
6 | ## Table of contents | |
7 | ||
8 | - [Internal Node.js thread pool](#internal-nodejs-thread-pool) | |
9 | - [Cluster vs Threads worker pools](#cluster-vs-threads-worker-pools) | |
10 | - [Fixed vs Dynamic pools](#fixed-vs-dynamic-pools) | |
11 | ||
12 | ## Internal Node.js thread pool | |
13 | ||
14 | Before to jump into each poolifier pool type, let highlight that **Node.js comes with a thread pool already**, the libuv thread pool where some particular tasks already run by default. | |
15 | Please take a look at [which tasks run on the libuv thread pool](https://nodejs.org/en/docs/guides/dont-block-the-event-loop/#what-code-runs-on-the-worker-pool). | |
16 | ||
17 | **If your task runs on libuv thread pool**, you can try to: | |
18 | ||
19 | - Tune the libuv thread pool size setting the [UV_THREADPOOL_SIZE](https://nodejs.org/api/cli.html#cli_uv_threadpool_size_size). | |
20 | ||
21 | and/or | |
22 | ||
23 | - Use poolifier cluster pools that are spawning child processes, they will also increase the number of libuv threads since that any new child process comes with a separated libuv thread pool. **More threads does not mean more fast, so please tune your application**. | |
24 | ||
25 | ## Cluster vs Threads worker pools | |
26 | ||
27 | **If your task does not run into libuv thread pool** and is CPU intensive then poolifier **thread pools** (_FixedThreadPool_ and _DynamicThreadPool_) are suggested to run CPU intensive tasks, you can still run I/O intensive tasks into thread pools, but performance enhancement is expected to be minimal. | |
28 | Thread pools are built on top of Node.js [worker_threads](https://nodejs.org/api/worker_threads.html) module. | |
29 | ||
30 | **If your task does not run into libuv thread pool** and is I/O intensive then poolifier **cluster pools** (_FixedClusterPool_ and _DynamicClusterPool_) are suggested to run I/O intensive tasks, again you can still run CPU intensive tasks into cluster pools, but performance enhancement is expected to be minimal. | |
31 | Consider that by default Node.js already has great performance for I/O tasks (asynchronous I/O). | |
32 | Cluster pools are built on top of Node.js [cluster](https://nodejs.org/api/cluster.html) module. | |
33 | ||
34 | If your task contains code that runs on libuv plus code that is CPU intensive or I/O intensive you either split it either combine more strategies (i.e. tune the number of libuv threads and use cluster/thread pools). | |
35 | But in general, **always profile your application**. | |
36 | ||
37 | ## Fixed vs Dynamic pools | |
38 | ||
39 | To choose your pool consider first that with a _FixedThreadPool_/_FixedClusterPool_ or a _DynamicThreadPool_/_DynamicClusterPool_ your application memory footprint will increase. | |
40 | By doing so, your application will be ready to execute in parallel more tasks, but during idle time your application will consume more memory. | |
41 | One good choice from poolifier team point of view is to profile your application using a fixed or dynamic worker pool, and analyze your application metrics when you increase/decrease the number of workers. | |
42 | For example you could keep the memory footprint low by choosing a _DynamicThreadPool_/_DynamicClusterPool_ with a minimum of 5 workers, and allowing it to create new workers until a maximum of 50 workers if needed. This is the advantage of using a _DynamicThreadPool_/_DynamicClusterPool_. | |
43 | But in general, **always profile your application**. |