| 1 | ## General Guidelines |
| 2 | Performance is one of the main target of these worker pool implementations, poolifier team wants to have a strong focus on this. |
| 3 | Poolifier already has a [benchmarks](./benchmarks/) folder where you can find some comparisons. |
| 4 | |
| 5 | ### Internal Node.js thread pool |
| 6 | |
| 7 | 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. |
| 8 | 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). |
| 9 | |
| 10 | **If your task runs on libuv thread pool**, you can try to: |
| 11 | |
| 12 | - Tune the libuv thread pool size setting the [UV_THREADPOOL_SIZE](https://nodejs.org/api/cli.html#cli_uv_threadpool_size_size). |
| 13 | |
| 14 | and/or |
| 15 | |
| 16 | - 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**. |
| 17 | |
| 18 | ### Cluster vs Threads worker pools |
| 19 | |
| 20 | **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. |
| 21 | Thread pools are built on top of Node.js [worker_threads](https://nodejs.org/api/worker_threads.html) module. |
| 22 | |
| 23 | **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. |
| 24 | Consider that by default Node.js already has great performance for I/O tasks (asynchronous I/O). |
| 25 | Cluster pools are built on top of Node.js [cluster](https://nodejs.org/api/cluster.html) module. |
| 26 | |
| 27 | 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). |
| 28 | But in general, **always profile your application**. |
| 29 | |
| 30 | ### Fixed vs Dynamic pools |
| 31 | |
| 32 | To choose your pool consider first that with a _FixedThreadPool_/_FixedClusterPool_ or a _DynamicThreadPool_/_DynamicClusterPool_ your application memory footprint will increase. |
| 33 | By doing so, your application will be ready to execute in parallel more tasks, but during idle time your application will consume more memory. |
| 34 | 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. |
| 35 | 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_. |
| 36 | But in general, **always profile your application**. |