When you run a Node.js application directly from the terminal using node app.js, the application stays alive only as long as the terminal session remains active. Close the terminal, and your application stops. This limitation becomes critical when deploying to production environments where services need to run continuously, restart automatically after failures, and handle system reboots gracefully.
Process managers like PM2 and forever exist to solve this fundamental challenge, transforming simple Node.js scripts into robust, production-ready services that run indefinitely. For teams building modern web applications, proper process management is essential for maintaining service availability and delivering reliable user experiences.
What You'll Learn
- How to install and configure PM2 for Node.js process management
- Starting, stopping, and managing running applications
- Comparing PM2 versus forever for different use cases
- Cluster mode for load balancing across CPU cores
- Startup scripts for server reboot persistence
- Monitoring and logging best practices
- Production deployment strategies
Let's explore how to keep your Node.js applications running continuously, automatically recovering from failures and maintaining availability around the clock.
Automatic Crash Recovery
Process managers restart applications automatically when they crash, minimizing downtime and maintaining service availability.
Load Balancing
PM2's cluster mode distributes incoming connections across multiple process instances, maximizing performance.
Centralized Logging
Collect and view logs from all running processes in one place, simplifying debugging and monitoring.
Zero-Downtime Deployments
Reload applications without interrupting active connections, ensuring seamless updates.
Startup Script Generation
Configure applications to start automatically when servers reboot, maintaining availability.
Resource Monitoring
Track memory usage, CPU consumption, and event loop metrics for all managed processes.
Installing PM2: The Production Standard
PM2 is an advanced production process manager for Node.js applications with built-in load balancer, zero-downtime reload, startup scripts, monitoring, and microservice management features. Installation follows the standard npm global package pattern, requiring only a single command to add PM2 to your system. The tool is cross-platform compatible, working consistently across Linux, macOS, and Windows environments. Once installed, PM2 becomes available globally and can manage any Node.js application on your system.
npm install pm2@latest -g
# or
yarn global add pm2
After installation, verify PM2 is available by checking its version:
pm2 --version
PM2 runs as a daemon, managing processes in the background even when you're not actively using it. This daemon-based architecture is fundamental to maintaining application availability continuously.
Installing Node.js and npm
If you haven't installed Node.js yet, use Node Version Manager (NVM) for easy version management:
# Install NVM (if not already installed)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
# Install the latest LTS version of Node.js
nvm install --lts
# Use the LTS version
nvm use --lts
Starting Applications with PM2
The simplest way to start, daemonize, and monitor your application is using the pm2 start command:
pm2 start app.js
Starting Different Application Types
PM2 can run various types of applications beyond pure JavaScript files:
# Start a Node.js script
pm2 start app.js
# Start a bash script
pm2 start bashscript.sh
# Start a Python application with watch mode
pm2 start python-app.py --watch
# Start a binary with arguments
pm2 start binary-file -- --port 1520
Common Options
PM2 offers numerous options to customize application behavior:
| Option | Description |
|---|---|
--name <name> | Assign a custom name for easier identification |
--watch | Enable file watching and automatic restart on changes |
--max-memory-restart <200MB> | Restart when memory exceeds threshold |
--log <path> | Specify custom log file location |
-- | Pass arguments to the script |
--restart-delay <ms> | Delay between automatic restarts |
--time | Prefix logs with timestamps |
--no-autorestart | Disable automatic restart |
--cron <pattern> | Schedule forced restarts with cron |
--no-daemon | Run in foreground (no daemon mode) |
Example: Starting with Custom Configuration
# Start with custom name, log location, and restart delay
pm2 start app.js --name "my-api" --log /var/log/pm2/app.log --restart-delay 5000
# Start with memory limit and watch mode for development
pm2 start server.js --name "dev-server" --max-memory-restart 100MB --watch
# Start with environment variables
pm2 start app.js --env production
Managing Running Processes
Once applications are running under PM2's management, you can control their state through a consistent set of commands.
Essential Management Commands
# Restart an application (stops and starts again)
pm2 restart app_name
# Reload with zero downtime (starts new instances before stopping old ones)
pm2 reload app_name
# Stop an application (preserves process in PM2 list)
pm2 stop app_name
# Delete an application (removes from PM2 entirely)
pm2 delete app_name
# Manage all processes
pm2 restart all
pm2 reload all
pm2 stop all
pm2 delete all
Listing Running Applications
# Display all managed applications with status
pm2 list
pm2 ls
pm2 status
This command shows:
- Process ID (pid)
- Application name
- Current status (online, stopped, errored)
- Memory usage
- CPU consumption
- Number of restarts
- Uptime
Targeting Specific Processes
Commands can target processes by name, ID, or handle all processes:
# By process name
pm2 restart my-api
pm2 stop my-api
# By process ID
pm2 restart 0
pm2 stop 2
# All processes
pm2 restart all
pm2 stop all
Getting Process Details
# Detailed information about a specific process
pm2 describe 0
# Display processes in JSON format
pm2 jlist
# Display processes in beautified JSON
pm2 prettylist
Understanding Forever: The Simpler Alternative
The forever npm module provides a simpler approach to running Node.js scripts continuously, focusing on basic process maintenance without PM2's extensive feature set. Installing forever follows the same pattern as PM2, using npm's global installation capability.
npm install forever -g
Forever Commands
# Start a script
forever start app.js
# List running processes
forever list
# Stop all processes
forever stopall
# Stop a specific process by index
forever stop 0
# Restart a process
forever restart 0
# View logs
forever logs
When to Use Forever
Forever is suitable for:
- Development environments and quick scripts
- Simple applications without scaling requirements
- Situations where PM2's complexity is unnecessary
- Quick prototypes and one-off scripts
For production deployments, PM2 is generally recommended due to its advanced features including cluster mode, startup scripts, and comprehensive monitoring capabilities.
Comparison: Forever vs PM2
| Feature | Forever | PM2 |
|---|---|---|
| Installation | Simple | Simple |
| Cluster Mode | Not supported | Built-in load balancer |
| Startup Scripts | Manual setup | Auto-generation |
| Monitoring Dashboard | Basic | Terminal + Web UI |
| Zero-Downtime Reload | No | Yes |
| Ecosystem Files | No | Yes |
| Log Management | Basic | Advanced |
| Process Metrics | Minimal | Comprehensive |
Cluster Mode for Load Balancing
PM2 includes automatic load balancing for Node.js applications that distributes HTTP, WebSocket, TCP, and UDP connections across spawned processes. Cluster mode leverages all available CPU cores, enabling a single Node.js application to handle significantly more concurrent connections.
Implementing cluster mode is a key strategy in web development services for building scalable applications that maximize server resources. By distributing load across multiple processes, applications can handle increased traffic without requiring horizontal scaling of entire servers.
Starting in Cluster Mode
# Use all available CPU cores
pm2 start app.js -i max
# Use a specific number of instances
pm2 start app.js -i 4
# Start with a name
pm2 start app.js -i max --name "api-cluster"
Scaling Applications
You can scale applications up or down dynamically:
# Scale to 3 additional workers
pm2 scale api +3
# Scale to exactly 5 workers total
pm2 scale api 5
# Scale down to 2 workers
pm2 scale api 2
How Cluster Mode Works
// cluster-mode.js - Example showing cluster awareness
const cluster = require('cluster');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
console.log(`Master process ${process.pid} is running`);
// Fork workers based on CPU count (or PM2's -i count)
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`Worker ${worker.process.pid} died`);
// PM2 will automatically restart in cluster mode
});
} else {
// Workers share the same port via PM2's load balancer
console.log(`Worker ${process.pid} started`);
require('./app.js'); // Your application entry point
}
Note: When using PM2's cluster mode, you don't need to implement cluster management in your code. PM2 handles the load balancing automatically. Your application code can be identical whether running in cluster mode or single instance mode.
Benefits of Cluster Mode
- Full CPU Utilization - Uses all available cores instead of being limited to single-thread
- Automatic Load Distribution - Connections are distributed evenly across instances
- High Availability - If one instance crashes, others continue serving traffic
- Zero Configuration - No external load balancer required
Ecosystem Files for Complex Configurations
For applications requiring sophisticated configuration, PM2 supports ecosystem files that define application settings in a structured JavaScript format. These files enable version-controlled configuration management and multi-application deployments.
Generating an Ecosystem File
pm2 ecosystem
This creates an ecosystem.config.js file with a template configuration.
Ecosystem File Example
// ecosystem.config.js
module.exports = {
apps: [
{
name: "api-server",
script: "./src/server.js",
instances: "max",
exec_mode: "cluster",
watch: false,
max_memory_restart: "500MB",
env: {
NODE_ENV: "development",
PORT: 3000
},
env_production: {
NODE_ENV: "production",
PORT: 8080
},
log_file: "/var/log/pm2/api.log",
time: true,
autorestart: true,
watch_delay: 1000,
ignore_watch: ["node_modules", "logs"],
max_restarts: 10,
min_uptime: "10s"
},
{
name: "worker-service",
script: "./workers/processor.js",
instances: 2,
exec_mode: "fork",
cron_restart: "0 2 * * *", // Restart daily at 2 AM
env: {
NODE_ENV: "development"
},
env_production: {
NODE_ENV: "production"
}
}
]
};
Starting from Ecosystem File
# Start all apps in the ecosystem file
pm2 start ecosystem.config.js
# Start specific app from ecosystem file
pm2 start ecosystem.config.js --only api-server
# Start in development environment
pm2 start ecosystem.config.js --env development
# Start in production environment
pm2 start ecosystem.config.js --env production
Ecosystem File Properties
| Property | Description |
|---|---|
name | Application name for identification |
script | Path to the application entry point |
instances | Number of instances or "max" for all CPUs |
exec_mode | "fork" for classic mode, "cluster" for cluster mode |
watch | Enable file watching |
max_memory_restart | Memory threshold for restart |
env | Environment variables (development) |
env_production | Environment variables (production) |
log_file | Custom log file path |
autorestart | Enable/disable auto-restart |
max_restarts | Maximum restarts in time window |
min_uptime | Minimum uptime before considering restart |
cron_restart | Schedule restarts with cron expression |
Startup Scripts for Server Reboots
A critical aspect of production deployments is ensuring applications survive server reboots. PM2 generates startup scripts that automatically launch managed processes when systems restart. The startup command detects your init system and generates appropriate configuration.
Generating Startup Script
pm2 startup
This command detects your init system (systemd, upstart, etc.) and generates the appropriate configuration. The output will show a command you need to run with sudo privileges.
Saving Process List
After enabling startup scripts, save the current process list:
pm2 save
This saves the list of processes PM2 should manage. On server reboot, PM2 will automatically start these processes.
Complete Setup Sequence
# 1. Generate startup script
sudo pm2 startup
# 2. Start your applications
pm2 start app.js --name "api"
pm2 start worker.js --name "worker"
# 3. Save the process list
pm2 save
# 4. Verify startup configuration
pm2 resurrect
Systemd Example (Manual Configuration)
If you need to configure systemd manually:
# /etc/systemd/system/pm2-init.service
[Unit]
Description=PM2 Process Manager
After=network.target
[Service]
Type=forking
User=www-data
ExecStart=/usr/local/bin/pm2 resurrect
ExecStop=/usr/local/bin/pm2 kill
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
# Enable the service
sudo systemctl enable pm2-init.service
sudo systemctl start pm2-init.service
Managing PM2 on System Boot
# Check PM2 status after reboot
pm2 list
# Manually resurrect processes
pm2 resurrect
# Kill PM2 daemon (stops all managed apps)
pm2 kill
# Show startup configuration
pm2 startup
Monitoring and Logs
PM2 provides multiple monitoring options ranging from terminal dashboards to web-based interfaces. Effective monitoring is crucial for maintaining application health and quickly identifying issues before they impact users. For teams implementing comprehensive DevOps practices, PM2's monitoring capabilities integrate well with broader observability strategies.
Real-Time Dashboard
The monit command launches a real-time terminal dashboard:
pm2 monit
This dashboard displays:
- CPU and memory usage per process
- Application logs (real-time)
- Event loop delay metrics
- Process status indicators
Viewing Logs
# Stream logs from all processes
pm2 logs
# View last 100 lines
pm2 logs --lines 100
# View logs from specific app
pm2 logs my-app
# Clear all logs
pm2 flush
# Reload logs (useful after log rotation)
pm2 reloadLogs
Log Configuration
You can configure log behavior in ecosystem files:
module.exports = {
apps: [{
name: "my-app",
script: "./app.js",
log_file: "/var/log/pm2/app.log",
time: true, // Add timestamps
log_date_format: "YYYY-MM-DD HH:mm:ss Z",
error_file: "/var/log/pm2/app-err.log",
out_file: "/var/log/pm2/app-out.log",
combine_logs: true, // Combine stdout/stderr
max_size: "10M", // Max log file size
max_restarts: 10
}]
};
Metrics Endpoint
PM2 can expose application metrics via HTTP:
# Enable web API
pm2 web
This starts a web server (usually on port 9615) that exposes JSON metrics for integration with monitoring tools.
PM2 Plus (Web Dashboard)
For comprehensive monitoring across multiple servers, PM2 Plus provides a web-based dashboard. Sign up at pm2.io and connect your PM2 installation:
pm2 plus
PM2 Plus features include:
- Cross-server monitoring dashboard
- Exception tracking
- Custom metrics
- Alerts and notifications
- Deployment history
Monitoring Best Practices
- Set up alerts for memory usage spikes or restart loops
- Review logs regularly for patterns indicating issues
- Monitor event loop lag to detect blocking operations
- Track restart counts - high values indicate instability
- Use log rotation to prevent disk space exhaustion
# Example: Set memory alert threshold (via ecosystem)
module.exports = {
apps: [{
name: "api",
script: "./api.js",
max_memory_restart: "300MB",
// PM2 will restart when memory exceeds 300MB
}]
};
Production Best Practices
Implementing robust process management requires following established best practices developed through production experience. These practices help ensure your Node.js applications remain stable, performant, and available even under adverse conditions.
Essential Best Practices
1. Always Configure Startup Scripts
# Generate and enable startup scripts BEFORE first production deployment
sudo pm2 startup
pm2 save
Unmanaged processes that don't survive reboots create availability gaps that may not be immediately apparent.
2. Use Ecosystem Files for All Deployments
// ecosystem.config.js - Version control your deployment config
module.exports = {
apps: [{
name: "production-api",
script: "dist/server.js",
instances: "max",
exec_mode: "cluster",
env_production: {
NODE_ENV: "production",
LOG_LEVEL: "info"
},
max_memory_restart: "500MB",
autorestart: true,
watch: false // Disable in production
}]
};
3. Configure Appropriate Restart Policies
{
"max_restarts": 10, // Max restarts in time window
"min_uptime": "10s", // Min uptime before considering restart
"restart_delay": 1000, // Delay between restarts
"exp_backoff_restart_delay": 100 // Exponential backoff
}
4. Implement Log Management
# Rotate logs daily with pm2-logrotate
pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 50M
pm2 set pm2-logrotate:retain 30
5. Monitor Application Health
// Expose health checks in your application
const http = require('http');
const server = http.createServer((req, res) => {
if (req.url === '/health') {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ status: 'ok', uptime: process.uptime() }));
} else {
res.writeHead(404);
res.end();
}
});
server.listen(3000);
Security Considerations
- Run with least privilege - Use dedicated service accounts
- Secure log files - Prevent sensitive data exposure
- Limit environment variables - Don't expose secrets in process listings
- Disable unnecessary features - Turn off
--watchin production
Deployment Checklist
Before deploying to production:
- Startup scripts are configured and tested
- Ecosystem file is version-controlled
- Log rotation is configured
- Memory limits are set appropriately
- Restart policies are configured
- Monitoring is set up (PM2 Plus or custom)
- Health check endpoints are implemented
- Process has been tested through simulated crash
- Load testing validates cluster mode configuration
Our web development services team follows these best practices for all production deployments, ensuring reliable and maintainable application infrastructure.
Frequently Asked Questions
Sources
-
Better Stack - Running Node.js Apps with PM2 (Complete Guide) - Comprehensive PM2 guide covering installation, features, clustering, deployment, and process management commands
-
PM2 Quick Start Documentation - Official documentation for PM2 including CLI commands, ecosystem files, cluster mode, startup scripts, and monitoring features
-
LogRocket - Running Node.js scripts continuously using forever - Focus on the forever npm module, setup instructions, and important forever commands for process management
-
GeeksforGeeks - How to run a node.js application permanently - Practical comparison of PM2 and forever modules with installation and usage examples