# Managing Node Applications with PM2

Node.js is an open-source JavaScript runtime built on Chrome's V8 engine, known for its speed and scalability in real-time and high-performance applications. Running Node applications in production comes with unique challenges — you need to handle unexpected crashes, manage processes, and ensure continuous uptime. PM2 is a production process manager for Node.js applications that simplifies this, letting you monitor, restart, and optimize your apps. This guide walks through installing PM2, running a sample Node.js app under it, and configuring PM2 for production use. By the end, you'll have a Node.js application managed by PM2 with automatic restarts, centralized logs, and startup persistence configured, following Node.js process management practices documented in [**Vultr Docs**](https://docs.vultr.com/how-to-manage-node-applications-with-pm2).

* * *

## Prerequisites

*   Access to your workstation as a non-root sudo user, running macOS, Linux, or Windows, with Node and npm installed.
    

## Install PM2 Using npm

**1\. Install PM2 via the npm package manager:**

```console
sudo npm install pm2 -g
```

## Create an Example Node.js Application

**1\. Navigate to your home directory:**

```console
cd ~
```

**2\. Create a file named** `app.js` **using a text editor such as** `vim`**:**

```console
vim app.js
```

**3\. Add the following code to the file:**

```javascript
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}/`);
});
```

Save and exit the file. This example app listens on port 3000 and responds to HTTP requests with the message "Hello World".

## Start the Application Using PM2

**1\. Start your Node.js application with PM2 (replace** `app.js` **with your entry file if needed):**

```console
pm2 start app.js
```

Your output should look similar to:

```plaintext
[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    │
└────┴────────────────────┴──────────┴──────┴───────────┴──────────┴──────────┘
```

Useful additional parameters when starting an app:

*   `--name <app_name>` - specify an application name
    
*   `--watch` - restart your application automatically when a file changes
    
*   `--max-memory-restart <memory>` - a memory limit that triggers an automatic restart when reached
    
*   `--log <log_file>` - specify a log file
    
*   `--restart-delay <delay>` - delay between automatic restarts in milliseconds
    
*   `--time` - prefix logs with time
    
*   `--no-autorestart` - turn off automatic application restarts
    
*   `--cron` - a cron job pattern for automatic application restarts
    
*   `--no-daemon` - do not run the application in a daemon process
    

Visit the [official documentation](https://pm2.keymetrics.io/docs/usage/application-declaration/#attributes-available) to view all available parameters.

## Manage the Application

**1\. Restart your PM2-managed application:**

```console
pm2 restart app
```

**2\. Reload your PM2-managed application:**

```console
pm2 reload app
```

**3\. Stop your PM2-managed application:**

```console
pm2 stop app
```

**4\. Delete your PM2-managed application:**

```console
pm2 delete app
```

## List All Applications

**1\. List all the applications managed by PM2:**

```console
pm2 list
```

## Display Logs

**1\. View the logs produced by your application in real time:**

```console
pm2 logs
```

**2\. View older logs by specifying the number of lines with the** `--lines` **flag:**

```console
pm2 logs --lines 200
```

## Monitor Resource Usage

**1\. Monitor the resources consumed by your applications in near real time:**

```console
pm2 monit
```

## Set Up a Web-Based Dashboard

**1\. Configure a web-based PM2 dashboard:**

```console
pm2 plus
```

Follow the prompts to create or log in to a PM2 account. If you don't have one, complete the required information and accept the license agreement. You'll see output during setup similar to:

```plaintext
[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: exampleuser
[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 `exampleuser` with your preferred username, `admin@example.com` with your login email address, and provide a strong password to secure your PM2 account. Then open the provided web address, log in with your PM2 account credentials, and start monitoring your applications through the PM2 Plus dashboard.

> PM2 Plus is a subscription-based offering that incurs a cost depending on the number of processes you want to monitor. Review the pricing details on the PM2 Plus page.

## Configure PM2 to Start on Server Boot

**1\. Generate a startup script and configure PM2 to start on server boot:**

```console
pm2 startup
```

Your output should look similar to:

```plaintext
[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
```

**2\. Copy the command from the previous output and run it to make the PM2 process persistent:**

```console
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
```

Your output should look similar to:

```plaintext
...
[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

**1\. Save the running applications to the list:**

```console
pm2 save
```

Your output should look similar to:

```plaintext
[PM2] Saving current process list...
[PM2] Successfully saved in /home/linuxuser/.pm2/dump.pm2
```

**2\. Restore the saved applications manually from the list if needed:**

```console
pm2 resurrect
```

Your output should look similar to:

```plaintext
[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

**1\. Print a list of outdated npm packages on your system:**

```console
npm outdated -g
```

This displays a list of globally installed npm packages that have newer versions available.

## Update PM2

**1\. Update the PM2 package via npm (this stops all running PM2 processes until the upgrade completes, causing downtime):**

```console
npm install pm2@latest -g
```

**2\. Perform an in-memory update of PM2:**

```console
pm2 update
```

## Best Practices and Security Considerations

### Prevent Downtime With Cluster Mode

Your PM2 processes may restart multiple times during their lifecycle, causing temporary downtime. Cluster mode runs multiple instances of your application, and when a restart is required, only one instance stops and restarts at a time while the others keep serving traffic.

**1\. Delete the application before switching to cluster mode:**

```console
pm2 delete app
```

**2\. Start the application in cluster mode, specifying the number of instances with the** `-i` **parameter:**

```console
pm2 start app.js -i 3
```

This starts three instances of your application in cluster mode using PM2.

**3\. Scale the application by specifying the new number of instances:**

```console
pm2 scale app 4
```

This scales your `app` application up to **4** instances.

### Eliminate Failed Requests With Graceful Shutdown

PM2 ensures graceful shutdowns by sending signals to your application so it can terminate cleanly, helping prevent data loss or corruption by allowing your app to finish active tasks before exiting:

1.  Before shutdown, PM2 sends a `SIGINT` signal to your application.
    
2.  Your application intercepts the signal.
    
3.  It finishes active requests and closes open resources like database connections.
    
4.  The application exits.
    

**1\. Add the following code to enable graceful shutdown in your application:**

```javascript
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();
});
```

This intercepts the `SIGINT` signal, logs a message to the console, closes the HTTP server, and exits the process cleanly.

## Next Steps

*   Enable cluster mode in production to eliminate downtime during restarts
    
*   Set up PM2 Plus (or another monitoring tool) for centralized visibility across multiple servers
    
*   Add graceful shutdown handling to any application that holds open connections or resources
    
*   Explore PM2's ecosystem file (`pm2.config.js`) to manage multiple apps and environments from one file
    

For the full guide with additional tips, visit the original article on [**Vultr Docs**](https://docs.vultr.com/how-to-manage-node-applications-with-pm2).
