PM2 is a popular process manager for Node.js applications that allows you to run, monitor, and scale your applications with ease. PM2 is designed to make your Node.js development and deployment more efficient and reliable, by providing features such as:
- Process management: You can start, stop, restart, delete, or list your Node.js processes with simple commands or a web interface.
- Load balancing: You can distribute the load of your applications across multiple CPU cores, by using cluster mode or process scaling.
- Monitoring: You can monitor the performance and status of your applications, such as CPU usage, memory usage, requests per second, errors, logs, and more.
- Logging: You can manage the logs of your applications, such as rotating, streaming, or flushing them.
- Watch and reload: You can enable watch mode to automatically reload your applications when the source code changes.
- Deployment: You can deploy your applications to remote servers with a single command, by using the PM2 deploy feature.
Check How to Manage Applications with PM2 for a complete tutorial.
What is Fork Mode?
Fork mode is the default mode of PM2, where it spawns a single process for each application. This mode is suitable for applications that use different versions of Node.js, or applications that are not networked, such as scripts, workers, or cron jobs.
Fork mode also supports some advanced features of PM2, such as:
- Cron restarts: You can specify a cron pattern to restart your application at a specific time or interval.
- Source map support: You can enable source map support to get the original source code location of errors in your application.
- Custom log formats: You can customize the format of the logs generated by your application, such as adding timestamps, colors, or prefixes.
To use fork mode, you can simply run your application with PM2 without any additional options, or specify the exec_mode as fork in your configuration file. For example:
# Run app.js in fork mode
pm2 start app.js
# Or via a configuration file
module.exports = {
apps : [
{
script : "app.js",
exec_mode : "fork"
}
]
}
The advantages of fork mode are:
- It allows you to run applications with different versions of Node.js, by using the node_args option to specify the path to the Node.js binary.
- It allows you to run applications that are not networked, such as scripts, workers, or cron jobs, by using the type option to specify the type of the application.
- It offers more flexibility and control over your applications, by allowing you to use custom environment variables, arguments, log formats, etc.
The disadvantages of fork mode are:
- It does not take advantage of the multi-core capabilities of your CPU, by creating only one process per application.
- It does not support some features of PM2 that are available in cluster mode, such as graceful reload, zero-downtime restart, and automatic port sharing.
- It requires more configuration and management, by requiring you to specify the options for each application individually.
What is Cluster Mode?
Cluster mode is a more advanced mode of PM2, where it creates multiple processes for each application, and distributes the incoming requests among them. This mode takes advantage of the multi-core capabilities of your CPU, and improves the performance and reliability of your applications.
Cluster mode is ideal for networked applications, such as HTTP, TCP, or UDP servers, that can handle concurrent requests from multiple clients. Cluster mode also supports some features of PM2 that are not available in fork mode, such as:
- Graceful reload: You can reload your application without losing any requests, by waiting for the existing connections to close before restarting the processes.
- Zero-downtime restart: You can restart your application without any downtime, by spawning new processes before killing the old ones.
- Automatic port sharing: You can run multiple processes on the same port, by using the cluster module of Node.js to enable load balancing and port sharing.
To use cluster mode, you need to pass the -i option to PM2, and specify the number of processes you want to create. You can also use max to create as many processes as the number of CPU cores, or -1 to create one less than the number of CPU cores. Alternatively, you can specify the exec_mode as cluster in your configuration file. For example:
# Run app.js in cluster mode with 4 processes
pm2 start app.js -i 4
# Or use max to auto-detect the number of CPU cores
pm2 start app.js -i max
# Or via a configuration file
module.exports = {
apps : [
{
script : "app.js",
instances : "max",
exec_mode : "cluster"
}
]
}
The advantages of cluster mode are:
- It improves the performance and reliability of your networked applications, by creating multiple processes that can handle the load and recover from failures.
- It supports some features of PM2 that are not available in fork mode, such as graceful reload, zero-downtime restart, and automatic port sharing.
- It offers better scalability and fault tolerance, by allowing you to add or remove processes dynamically, or use the PM2 reload feature to update your code without stopping your application.
The disadvantages of cluster mode are:
- It consumes more memory and CPU resources, by creating multiple processes for each application.
- It requires the same version of Node.js and networked applications, by using the cluster module of Node.js that reuses the same Node.js instance for each process.
- It does not support some advanced features of PM2 that are available in fork mode, such as cron restarts, source map support, and custom log formats.
How to Choose Between Fork and Cluster Mode?
The choice between fork and cluster mode depends on several factors, such as:
- The type of your application: If your application is networked and can handle concurrent requests, cluster mode is a better option. If your application is not networked or uses different versions of Node.js, fork mode is more suitable.
- The features you need: If you need features such as cron restarts, source map support, or custom log formats, fork mode is the only option. If you need features such as graceful reload, zero-downtime restart, or automatic port sharing, cluster mode is the preferred option.
- The trade-offs you are willing to make: Cluster mode offers better scalability and fault tolerance, but it also consumes more memory and CPU resources. Fork mode offers more flexibility and control, but it also requires more configuration and management.
To help you decide which mode to use, you can ask yourself the following questions:
- Do I need to run applications with different versions of Node.js, or applications that are not networked?
- Do I need features such as cron restarts, source map support, or custom log formats?
- Do I have enough memory and CPU resources to run multiple processes for each application?
- Do I need features such as graceful reload, zero-downtime restart, or automatic port sharing?
- Do I want to improve the performance and reliability of my networked applications?
If you answered yes to the first two questions, fork mode is the best option for you. If you answered yes to the last three questions, cluster mode is the best option for you. If you answered yes to some of the questions from both groups, you need to weigh the pros and cons of each mode, and choose the one that best suits your needs and preferences.
What are the best practices for using cluster mode in PM2?
Cluster mode is a powerful feature of PM2 that can boost the performance and reliability of your networked applications. However, to use cluster mode effectively, you need to follow some best practices, such as:
- Use the same version of Node.js for all your applications in cluster mode, by using the
node_args option
to specify the path to the Node.js binary. This will ensure that the cluster module of Node.js works properly and consistently across all your processes. - Use the
max_memory_restart
option to specify the maximum memory limit for each process in cluster mode. This will prevent memory leaks and optimize the memory usage of your applications. - Use the
wait_ready
option to enable the graceful reload feature in cluster mode. This will allow your processes to send a ready signal to PM2 when they are ready to receive requests, and wait for the existing connections to close before restarting. This will ensure that no requests are lost or interrupted during the reload process. - Use the
listen_timeout
and kill_timeout options to adjust the timeout values for the graceful reload feature in cluster mode. The listen_timeout option specifies the maximum time to wait for the ready signal from the processes, and the kill_timeout option specifies the maximum time to wait for the connections to close before killing the processes. These options will help you avoid errors or delays during the reload process. - Use the
pm2 reload
command to update your code without stopping your application in cluster mode. This command will spawn new processes with the updated code, and replace the old processes gradually. This will ensure that your application is always running and serving requests, even during the update process.
Here is an example of a configuration file that uses cluster mode with some of the best practices mentioned above:
module.exports = {
apps : [
{
script : "app.js",
instances : "max",
exec_mode : "cluster",
node_args : "/usr/local/bin/node",
max_memory_restart : "300M",
wait_ready : true,
listen_timeout : 5000,
kill_timeout : 5000
}
]
}
##Conclusion
PM2 is a powerful tool for running, monitoring, and scaling your applications. It offers two modes of operation: fork and cluster, that have different advantages and disadvantages. You should choose the mode that best suits your application type, features, and trade-offs. You can also switch between the modes easily by changing the options or the configuration file of PM2. We hope this article helped you understand the difference between fork and cluster mode in PM2, and how to choose the best one for your projects.