Managing Node.js Applications with PM2
Node.js is an open-source runtime for JavaScript that allows execution of JavaScript code outside the browser. It is powered by Chrome’s V8 engine, known for speed and scalability, making it suitable for real-time and high-performance applications. Running Node applications in production comes with unique challenges — handling unexpected crashes, managing processes, and ensuring continuous uptime. PM2 is a Production Process Manager for Node.js applications that simplifies these tasks by providing monitoring, restart, and optimization features.
This guide explains how to manage Node.js applications using PM2, highlights its core features, and outlines best practices for production environments.
Prerequisites
Ensure you have access to your workstation as a non-root sudo user running macOS, Linux, or Windows with Node and NPM installed.
Install PM2 Using NPM
Install PM2 via the NPM package manager:
$ sudo npm install pm2 -g
Create an Example Node.js Application
Follow these steps to create a sample Node.js application.
Navigate to the Home Directory
$ cd ~
Create the Application File
Create a file named app.js with a text editor such as vim:
$ vim app.js
Add Code to the File
Insert the following code into the file:
const http = require('http');
const hostname = '0.0.0.0';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
The app.js file above is a simple Node.js web application that listens on port 3000. When it receives an HTTP request, it responds with the message “Hello World”.
Start the Application Using PM2
Start your Node.js application with PM2. Replace app.js with your application’s entry file if needed:
$ pm2 start app.js
Your output should look similar to this:
[PM2] Starting /home/linuxuser/app.js in fork_mode (1 instance)
[PM2] Done.
┌────┬────────────────────┬──────────┬──────┬───────────┬──────────┬──────────┐
│ id │ name │ mode │ ↺ │ status │ cpu │ memory │
├────┼────────────────────┼──────────┼──────┼───────────┼──────────┼──────────┤
│ 0 │ app │ fork │ 0 │ online │ 0% │ 4.4mb │
└────┴────────────────────┴──────────┴──────┴───────────┴──────────┴──────────┘
Additional Parameters
PM2 provides extra parameters to manage your application:
--name <app_name>– specify an application name--watch– restart automatically when a file changes--max-memory-restart <memory>– set a memory threshold for auto-restart--log <log_file>– define a log file--restart-delay <delay>– add a delay between automatic restarts (ms)--time– add timestamps to logs--no-autorestart– disable automatic restarts--cron– use a cron job pattern for restarts--no-daemon– prevent the app from running as a daemon
Visit the official documentation to see the full list of parameters.
Manage the Application
Use PM2 to manage your Node.js application with actions like restart, reload, stop, and delete.
Restart the Application
$ pm2 restart app
Reload the Application
$ pm2 reload app
Stop the Application
$ pm2 stop app
Delete the Application
$ pm2 delete app
List All Applications
List all applications currently managed by PM2:
$ pm2 list
Display Logs
View the logs generated by your application in real-time:
$ pm2 logs
To view older logs, specify the number of lines with the --lines flag:
$ pm2 logs --lines 200
Monitor the Resource Usage
Monitor the resources consumed by your applications in near real time:
$ pm2 monit
Set up a Web-Based Dashboard
Configure a web-based PM2 dashboard with the following command:
$ pm2 plus
Follow the prompts to either create or log in to your PM2 account. If you don’t already have one, provide the required details and accept the license agreement.
You’ll see output similar to the following:
[PM2 I/O] Do you have a pm2.io account? (y/n) n
[PM2 I/O] No problem! We just need a few details to create your account.
[PM2 I/O] Please choose a username: vultrexampleuser
[PM2 I/O] Please choose an email: admin@example.com
[PM2 I/O] Please choose a password: ************
...
[PM2 I/O] Do you accept the terms and privacy policy (https://pm2.io/legals/terms_conditions.pdf)? (y/n) y
[PM2 I/O] Successfully authenticated
[PM2 I/O] Successfully validated
[+] PM2+ activated!
[PM2 I/O] Successfully connected to bucket PM2 Plus Monitoring
[PM2 I/O] You can use the web interface here: https://app.pm2.io/#/bucket/67cb27ccd623d57f6d4c63c0
Replace vultrexampleuser with your preferred username, admin@example.com with your login email, and provide a strong password to secure your account.
Next Steps
- Open a web browser and go to the provided URL.
- Log in with your PM2 credentials.
- Start monitoring and managing applications through the PM2 Plus dashboard.
Note: PM2 Plus is a subscription-based service with costs depending on the number of processes you want to monitor. Check the PM2 Plus pricing page for details.
Configure PM2 to Start on Server Boot
Generate a startup script and configure PM2 to launch on server boot:
$ pm2 startup
Your output should look like this:
[PM2] To setup the Startup Script, copy/paste the following command:
sudo env PATH=$PATH:/home/linuxuser/.nvm/versions/node/v22.14.0/bin /home/linuxuser/.nvm/versions/node/v22.14.0/lib/node_modules/pm2/bin/pm2 startup systemd -u linuxuser --hp /home/linuxuser
Copy the command from the output and execute it to make the PM2 process persistent:
$ sudo env PATH=$PATH:/home/linuxuser/.nvm/versions/node/v22.14.0/bin /home/linuxuser/.nvm/versions/node/v22.14.0/lib/node_modules/pm2/bin/pm2 startup systemd -u linuxuser --hp /home/linuxuser
The output will resemble this:
...
[PM2] Writing init configuration in /etc/systemd/system/pm2-linuxuser.service
Created symlink /etc/systemd/system/multi-user.target.wants/pm2-linuxuser.service → /etc/systemd/system/pm2-linuxuser.service.
...
Configure Applications to Start on Server Boot
To ensure your PM2 applications start automatically on server boot, save them into a list:
Save Running Applications
$ pm2 save
Expected output:
[PM2] Saving current process list...
[PM2] Successfully saved in /home/linuxuser/.pm2/dump.pm2
Restore Applications Manually
If you need to restore saved applications manually from the list, use this command:
$ pm2 resurrect
The output will look like this:
[PM2] Resurrecting
[PM2] Restoring processes located in /home/linuxuser/.pm2/dump.pm2
[PM2] Process /home/linuxuser/app.js restored
┌────┬────────────────────┬──────────┬──────┬───────────┬──────────┬──────────┐
│ id │ name │ mode │ ↺ │ status │ cpu │ memory │
├────┼────────────────────┼──────────┼──────┼───────────┼──────────┼──────────┤
│ 0 │ app │ fork │ 0 │ online │ 0% │ 21.3mb │
└────┴────────────────────┴──────────┴──────┴───────────┴──────────┴──────────┘
Check for Updates
Print a list of outdated NPM packages on your system:
$ npm outdated -g
This command shows a list of globally installed NPM packages that have newer versions available.
Update PM2
Update the PM2 package via NPM. The update stops all running PM2 processes until the upgrade is completed, causing downtime for your applications:
$ npm install pm2@latest -g
Perform an in-memory update of PM2:
$ pm2 update
Best Practices and Security Considerations
Prevent Downtime With Cluster Mode
PM2 processes may restart multiple times during their lifecycle, which can cause temporary downtime. Use PM2’s cluster mode to minimize downtime. Cluster mode runs multiple instances of your application, ensuring that when one instance restarts, the others remain available to serve traffic.
First, delete the application before enabling cluster mode:
$ pm2 delete app
Start the application in cluster mode, specifying the number of instances with the -i parameter:
$ pm2 start app.js -i 3
This command launches three instances of your application in cluster mode using PM2.
You can scale the application by specifying the new number of instances:
$ pm2 scale app 4
This command scales the application to four instances.
Eliminate Failed Requests With Graceful Shutdown
PM2 ensures graceful shutdowns by sending signals to your application, allowing it to exit cleanly. This prevents data loss or corruption by giving the app time to finish active tasks before shutting down.
PM2 manages graceful shutdowns as follows:
- Before shutdown, PM2 sends a
SIGINTsignal to the application. - The application intercepts the signal.
- It finishes active requests and closes resources such as database connections.
- The application exits.
Add the following code to enable graceful shutdown in your application:
process.on('SIGINT', function() {
// sigint signal received, log a message to the console
console.log('Shutdown signal intercepted');
// close the http server
server.close();
// exit the process
process.exit();
});
The code above enables graceful shutdown. It intercepts the SIGINT signal, logs a message, closes the HTTP server, and exits the process cleanly.
Conclusion
In this article, you learned how to install and use PM2 to manage Node.js applications in production. You configured PM2 to start applications automatically on system boot, monitored resource usage, viewed logs in real time, and set up the web-based PM2 Plus dashboard. By following these steps, you can keep Node.js applications running reliably, recover from crashes automatically, and simplify operations with PM2’s extensive feature set. For more information, please visit the official documentation.


