Running Node.js Scripts Continuously Forever

Master process management with PM2 and forever to keep your Node.js applications running reliably in production

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.

Why Process Management Matters

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:

OptionDescription
--name <name>Assign a custom name for easier identification
--watchEnable 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
--timePrefix logs with timestamps
--no-autorestartDisable automatic restart
--cron <pattern>Schedule forced restarts with cron
--no-daemonRun 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

FeatureForeverPM2
InstallationSimpleSimple
Cluster ModeNot supportedBuilt-in load balancer
Startup ScriptsManual setupAuto-generation
Monitoring DashboardBasicTerminal + Web UI
Zero-Downtime ReloadNoYes
Ecosystem FilesNoYes
Log ManagementBasicAdvanced
Process MetricsMinimalComprehensive

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

  1. Full CPU Utilization - Uses all available cores instead of being limited to single-thread
  2. Automatic Load Distribution - Connections are distributed evenly across instances
  3. High Availability - If one instance crashes, others continue serving traffic
  4. 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

PropertyDescription
nameApplication name for identification
scriptPath to the application entry point
instancesNumber of instances or "max" for all CPUs
exec_mode"fork" for classic mode, "cluster" for cluster mode
watchEnable file watching
max_memory_restartMemory threshold for restart
envEnvironment variables (development)
env_productionEnvironment variables (production)
log_fileCustom log file path
autorestartEnable/disable auto-restart
max_restartsMaximum restarts in time window
min_uptimeMinimum uptime before considering restart
cron_restartSchedule 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

  1. Set up alerts for memory usage spikes or restart loops
  2. Review logs regularly for patterns indicating issues
  3. Monitor event loop lag to detect blocking operations
  4. Track restart counts - high values indicate instability
  5. 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

  1. Run with least privilege - Use dedicated service accounts
  2. Secure log files - Prevent sensitive data exposure
  3. Limit environment variables - Don't expose secrets in process listings
  4. Disable unnecessary features - Turn off --watch in 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

Ready to Deploy Your Node.js Application?

Our team of experienced developers can help you build, deploy, and manage production-ready Node.js applications with proper process management, monitoring, and scaling strategies.

Sources

  1. Better Stack - Running Node.js Apps with PM2 (Complete Guide) - Comprehensive PM2 guide covering installation, features, clustering, deployment, and process management commands

  2. PM2 Quick Start Documentation - Official documentation for PM2 including CLI commands, ecosystem files, cluster mode, startup scripts, and monitoring features

  3. LogRocket - Running Node.js scripts continuously using forever - Focus on the forever npm module, setup instructions, and important forever commands for process management

  4. GeeksforGeeks - How to run a node.js application permanently - Practical comparison of PM2 and forever modules with installation and usage examples