Software

What Is PM2? Managing Node.js Apps in Production

Talha Aslan 20 min read 4 views

What is PM2?

PM2 is a process manager for Node.js applications. It runs your app in the background, restarts it when it crashes, collects its logs, spreads it across CPU cores and brings it back after a server reboot. You start, watch and update everything from one command line tool.

A Node.js app is normally one process. If that process hits an error and exits, your site goes down with it. PM2 watches the process all the time and brings it back up. So an app that crashes at midnight does not stay offline until morning.

People who search for what is PM2 usually want to know two things: is it hard to set up, and do I really need it? Setup takes one command. However, whether you need it depends on how important the app is. For example, a test project can live in a terminal, but a site with real customer traffic needs a process manager.

We are a digital marketing and web team, not a hosting company. This guide follows the PM2, Node.js and systemd documentation. Try every command on a staging copy first, then move to production.

Also, we do not cover installing Node.js or copying your app to the server here. This article starts after the app already runs on the server and focuses on day to day operation. If you want to know what the server side code is, read our backend development guide.

What is PM2 and why isn't the node command enough?

When you type node app.js in a terminal, the app stays tied to that session. If your SSH connection drops or you close the window, the process usually ends. If the app throws an error and exits, nobody restarts it.

On a live site, neither case is acceptable. In addition, the app should start on its own when the server reboots. PM2 closes all of these gaps:

  • First, it runs the app in the background, independent of your session.
  • Second, it restarts a crashed process automatically.
  • Then it brings the app back when the server boots.
  • Finally, it gathers logs in one place and lets you follow them live.

In other words, PM2 does not change your code. It adds an operations layer around it. When the people who write the code and the people who run the server are different, that layer becomes a shared language.

How do you start an app with PM2?

According to the official PM2 docs, you install it globally with npm. Then you pass the entry file of your app and start it. The commands below are examples, so replace the file and app names with your own.

npm install pm2@latest -g
pm2 start app.js --name example-app
pm2 list
pm2 logs example-app

The first command installs PM2. Next, the second starts the app and sends it to the background. After that, the third lists every app PM2 manages. Finally, the fourth streams the logs of that app live.

You can add more flags when you start an app. For example, the docs describe --watch, which restarts on file changes, and --max-memory-restart, which renews the process when it passes a memory limit. We look at both below.

A global install may need extra permissions. If you do not have them, or if you use shared hosting, then do not force the install. Ask your provider how they run Node.js apps.

What is the difference between start, restart, reload, stop and delete?

These five commands look alike at first, but they behave differently. The gap between restart and reload matters most on a live site. For example, here is a short comparison based on the official descriptions.

CommandWhat it doesWhen you use it
pm2 startStarts the app and adds it to the PM2 listThe first launch
pm2 restartStops the process and starts it againAfter a code or config change, if a short gap is fine
pm2 reloadAims for a zero downtime restart of networked appsLive updates in cluster mode
pm2 stopStops the process but keeps it in the listShort maintenance
pm2 deleteRemoves the process from the PM2 listWhen you retire the app for good

The practical takeaway is simple. If you only want to pause an app, then use stop. Reach for delete only when you want it gone from the list, otherwise you may remove the app by accident.

What is an ecosystem file and how do you write one?

Remembering long command line flags every time is hard. So PM2 lets you collect your settings in a configuration file. The docs call it ecosystem.config.js, and the pm2 ecosystem command generates a template.

The file exports an object with an array named apps. In practice, you write one object per app. The short example below uses the field names from the documentation.

module.exports = {
  apps: [{
    name: "example-app",
    script: "./app.js",
    cwd: "/srv/example-app",
    instances: 1,
    exec_mode: "fork",
    max_memory_restart: "300M",
    env: { NODE_ENV: "development" },
    env_production: { NODE_ENV: "production" }
  }]
}

You run it with pm2 start ecosystem.config.js. Also, keeping this file in version control with your project means your team can track every setting change.

The apps array can hold several objects. For example, you can define the web front end and a background worker as separate apps in one file. Then one command starts both, and you can renew just one of them when needed.

The docs also mention a deployment section in the ecosystem file. In short, it holds SSH details, Git references and commands that run before or after a release. Shipping code is a separate topic, so we leave it out here.

Which ecosystem settings matter most?

The documentation lists many fields. Below are the ones you will touch most often in daily operation. Treat the values as examples and choose them for your own app.

  • name: The app name inside PM2, which you use in commands.
  • script: The path to the entry file of the app.
  • cwd: The working directory where the app starts.
  • instances and exec_mode: The number of processes, and fork or cluster mode.
  • autorestart: Restarts the app after a crash. According to the docs, the default is true.
  • watch: Reloads the app when files change.
  • max_memory_restart: Renews the process above a memory limit, for example "150M".
  • error_file, out_file and log_date_format: The log file locations and the time format.

We do not recommend turning on watch in production. Files such as uploads or logs change all the time, so the app may restart for no reason. Still, it is handy on a development machine.

How do you manage environment variables and production settings?

Per the docs, the env field holds default variables. The env_production and env_development fields hold values for a specific environment. On the live server you start the app like this:

pm2 start ecosystem.config.js --env production

So the same file serves both test and live. In other words, only the values of the environment you choose take effect. Also, this approach saves you from copying code between environments.

What is PM2 from an environment point of view? It is a tool that runs one app with different settings from a single file. Still, check once which variable the code reads in which environment before you go live.

However, do not write passwords, API keys or database credentials into the ecosystem file and push it to a repository. Because this file usually lands in version control, treat it as readable by everyone with repository access. Keep secrets in a protected configuration source on the server.

If secret handling is beyond your comfort zone, plan it together with whoever runs the server. For instance, a badly managed key can be a serious hole on its own. Our OWASP Top 10 guide summarizes the common mistakes.

What is cluster mode and when should you use it?

By default a Node.js app runs on a single core. For example, if your server has four cores, three of them may sit idle. PM2 cluster mode uses the built in Node.js cluster module to spread your app across several cores. You do not have to change your code.

pm2 start app.js -i max

According to the docs, an instances value of 0 or max uses all CPUs. A value of -1 means all CPUs minus one. Finally, a specific number starts exactly that many processes.

The Node.js documentation says the cluster module shares connections between workers in a round robin way on every platform except Windows. Also, all workers share the same port. So you do not need a separate port or an extra load balancer for this.

On a small site, one process is often enough. Instead, think about cluster mode when you see heavy traffic or CPU load. Measure first, then multiply.

You can change the process count while the app runs with the pm2 scale command from the docs. For example, pm2 scale example-app 2 sets the number of workers of that app to two. That is one of the strongest answers to what is PM2: you change capacity without writing code.

Why must your app be stateless in cluster mode?

The PM2 docs set one clear condition for cluster mode: the app must be stateless. That means sessions, WebSocket connections and local data must not live in process memory. The reason is simple, because two requests in a row can reach different processes.

For example, if the first process keeps a user session in memory, the second request may land on another process. The user then looks logged out. On an online shop, that means an empty cart, and lost conversions follow directly.

So the fix is to move shared state out of the processes. The docs point to external stores such as Redis or MongoDB for this. We explain Redis and Memcached in our caching guide, so we do not repeat it here.

If your app is not stateless, talk to your developers before you turn on cluster mode. In short, this is an architecture decision more than a PM2 setting.

How does reload give you zero downtime updates?

According to the PM2 docs, reload restarts the processes one by one in cluster mode. So while one process restarts, the others keep serving requests. The restart command, by contrast, kills the process at once and creates it again, which can cause a short gap.

pm2 reload example-app

The docs describe reload in a cluster context. In fork mode there is only one process, so do not assume zero downtime without testing it in your own setup. We suggest building a staging environment for that test.

Cleaning up on shutdown matters too. The docs suggest catching the SIGINT signal to do work such as closing database connections. As a result, fewer half finished operations remain.

Still, reload does not solve a database schema change or an incompatible code version by itself. Two versions will run side by side for a while, so your changes must stay backward compatible.

Where does PM2 keep logs and how do you read them?

Per the docs, PM2 writes logs to the $HOME/.pm2/logs folder by default. Then the pm2 logs command streams all of them live. You can also pass an app name to follow only one app.

pm2 logs
pm2 logs example-app
pm2 logs --lines 200

When you start an app, -o sets the output file and -e sets the error file. Also, the --time flag adds a timestamp to each line. In cluster mode, --merge-logs joins the logs of all processes into one file.

When you debug, look at the error file first. The last lines before a crash often show the cause. Also try our log file analyzer if you want to inspect access logs.

If you need machine readable output, the pm2 logs --json option from the docs helps. You can then feed log lines into an analysis tool or a script more easily. However, review the content before you send raw logs to any third party service.

Never print passwords or personal data into logs. Such data can stay in files for years, often unnoticed. It also creates needless risk under GDPR rules.

How do you keep log files from filling the disk?

Because logs grow all the time, they need rotation. Without rotation, the files will fill the disk one day and the app will crash. That said, this silent risk is easy to miss.

The docs describe two routes. The first is the community module pm2-logrotate:

pm2 install pm2-logrotate

The second route uses the system's own rotation tool. According to the docs, the command sudo pm2 logrotate -u username creates a configuration at /etc/logrotate.d/pm2-username with weekly rotation and compression. So you replace username with your own user name.

The pm2 flush command clears all log files. Therefore use it with care if you want to keep history. The docs also say you can switch off disk logging by pointing out_file and error_file to /dev/null. We advise against it, because it makes debugging harder.

How does pm2 startup bring the app back after a reboot?

A server can reboot for maintenance or without warning. When that happens, PM2 stops too, so your app stops with it. The pm2 startup command detects your init system and generates a script that starts PM2 at boot.

The docs say the command prints a sudo line. You must copy and run that line exactly as printed. After that, you save the current app list with pm2 save.

pm2 startup
pm2 save

According to the docs, pm2 resurrect restores the saved list by hand, and pm2 unstartup removes the whole setup. The automatic restore at boot relies on that saved list.

One important detail: run pm2 save again whenever you add or remove an app. Otherwise the old list comes back after a reboot. Forgetting this is one of the most common surprises.

The docs state that PM2 detects the init system itself. Supported ones include systemd, upstart, launchd, openrc, rcd and systemv. Most current Linux distributions use systemd, so you usually see a systemd script. In short, PM2 does not handle boot on its own; it leaves an entry in the operating system's mechanism.

Why should you renew startup after a Node.js upgrade?

The startup script uses the Node.js path from the moment you created it. The warning in the docs is clear: after you upgrade Node.js, run pm2 unstartup first and then pm2 startup again. That way PM2 uses the current binary.

If you skip this step, everything looks normal at first. However, when the server reboots, PM2 may look for the old path and the app may not start. The outage appears exactly when you least expect it.

The docs also let you run under another user with the -u and --hp options. Our advice is not to run the app as root. Use a limited user that exists only for this app.

A Node.js upgrade can also affect your dependencies. So test the upgrade on a staging copy first. Check the current stable release on the Node.js website.

How do you monitor an app with PM2?

PM2 ships with a few built in monitoring tools. The pm2 list command summarizes the state. The pm2 monit command opens a live dashboard in the terminal. With pm2 describe you read the details of one process.

  • pm2 list: Shows the status of all apps.
  • pm2 monit: Gives you a live terminal dashboard.
  • pm2 describe 0: Shows the details of process number zero.
  • pm2 plus: According to the docs, a separate web interface that watches several servers.

The max_memory_restart setting is a safety net. It renews an app that leaks memory once it passes the limit. But it does not fix the leak, it only hides the symptom. Your developers must make the real fix.

Someone must own the monitoring. Write down who looks at an alert and who you call for help. Knowing what is PM2 is not enough; you also need to know whom the app tells when it crashes at three in the morning. Even a simple contact list makes a big difference.

Looking from the outside matters too. A process can be alive while the site does not answer. With our is it down tool you can check whether your page is reachable from the outside.

What is PM2 and is it the same as systemd?

Partly. Both keep a process alive and restart it after a crash. However, systemd is the init system of Linux itself, while PM2 is a tool written only for Node.js. That difference shapes your choice.

CriterionPM2systemd
ScopeNode.js processesAny kind of service
Cluster modeBuilt in, one flagNone; you design it in the app
Log handlingpm2 logs, its own folderSystem journal via journalctl
Start at bootpm2 startup and pm2 saveService file and enable
Extra dependencyInstall PM2 with npmComes with Linux
Team familiarityFamiliar to Node.js developersFamiliar to system administrators

In short, PM2 gives Node.js developers convenience, while systemd gives one uniform way to manage every service. Running both for the same app is usually unnecessary.

How do you run the same Node.js app with systemd?

If you prefer not to use PM2, systemd alone can be enough. You write a service file. The example below uses field names from the systemd documentation, while the paths and the user name are assumptions.

[Unit]
Description=Example Node.js app
After=network.target

[Service]
User=exampleuser
WorkingDirectory=/srv/example-app
ExecStart=/usr/bin/node app.js
Restart=on-failure
RestartSec=5
Environment=NODE_ENV=production

[Install]
WantedBy=multi-user.target

According to the manual, Restart defaults to no, so the service does not restart after a crash. You therefore need to write on-failure or always. RestartSec is the wait before the restart.

You can find the path of the node binary with command -v node. After you place the service file, you use systemctl daemon-reload and systemctl enable --now. Then you read the logs with journalctl -u.

Instead of writing secrets into the service file, you can load them from a file with EnvironmentFile, a sibling of the Environment setting. Restrict the file so that only the service user can read it. Also keep it out of your repository.

How do you choose between PM2, systemd and Docker?

The right choice depends on your team and your infrastructure. For a small Node.js app on one server, PM2 is a quick and familiar answer. If the server already runs many services, systemd gives one uniform way to manage them.

If you containerize the app, the picture changes. Docker has its own restart policies and usually moves the process manager outside the container. See our Docker guide for the details, as we do not repeat them here.

  • One server and a Node.js heavy team: PM2 is usually enough.
  • Mixed services and a team with a system administrator: consider systemd.
  • Several environments and repeatable setups: look at containers.

Whichever you pick, answer three questions. Does the app restart after a crash? Does it start when the server boots? Do the logs fill the disk? If you cannot say yes to all three, the setup is incomplete.

These three questions hold for any tool. Also weigh what your team knows. The person who rescues the system at midnight should know the tool, and that tool is often the better pick. Even the most advanced setup is a risk if nobody understands it.

When should you leave PM2 management to your hosting provider?

Let us be honest: you do not have to do everything yourself. If you have no server access on shared hosting or a managed plan, do not try to install PM2. If your provider supports Node.js, use that support.

Even on a VPS, some decisions are safer in expert hands. Firewalls, SSL, user permissions and backups come first. One wrong setting can take the site down or expose it.

  • Talk to your provider about putting the app behind a reverse proxy instead of exposing it directly.
  • For the certificate and renewal routine, read our SSL certificate guide.
  • Do not change the production database structure without a backup; our backup strategy guide helps.
  • If you see an attack or unusual traffic, ask your hosting provider for help right away.

If you have not chosen hosting yet, our guide on how to choose web hosting lists the criteria. Attach log samples and the steps you tried to your support request.

This is not a weakness but a sensible division of work. Spending your time on marketing and product is often more productive than owning server security. Learning what is PM2 and how it works helps you talk to your provider, but it does not mean you must do everything yourself.

How does an app outage affect your marketing budget?

It may sound technical, but downtime hits marketing directly. If an ad click lands on a broken page, the budget goes to waste. The visitor also gets a bad first impression of your brand.

A fast and stable server is also part of the search experience. We cover how site speed affects SEO and how page speed affects ecommerce sales in separate guides. PM2 sits at the bottom of that chain: is the app up or not?

So before a big campaign, we suggest this check:

  1. Test that the app restarts on its own after a crash.
  2. Reboot the server and confirm the app starts by itself.
  3. Check the size of the log folder and the rotation setting.
  4. Measure the site from the outside with a tool.

The list is short, yet it prevents most of the costly surprises on campaign day. For broader software and infrastructure support, see our custom software development service.

What are the most common mistakes with PM2?

The list below collects mistakes that come from misreading the documented features. All of them are avoidable.

  • Skipping pm2 save: The app does not return after a reboot.
  • Upgrading Node.js without renewing startup: The boot script keeps the old path.
  • Turning on watch in production: It causes needless restarts.
  • Not setting up log rotation: The disk fills and the app stops.
  • Running a stateful app in cluster mode: Sessions disappear.
  • Writing secret keys into the ecosystem file: They can leak into the repository.
  • Running the app as root: A possible hole affects the whole server.

Use this list as a checklist. Verify each item one by one in your own setup.

Teams usually notice these mistakes after the first outage. A team that knows what is PM2 and what it does from the start can run the same checks without an outage. In short, the cheapest maintenance is the check you do in advance.

Which steps do you follow before rolling out PM2?

Small, ordered steps are the safest way. The flow below folds the sections above into one plan. Try each step on a staging environment first.

  1. Start the app with a name using pm2 start and confirm it with pm2 list.
  2. Move the settings into an ecosystem file and run it with --env production.
  3. Turn on cluster mode with the instances setting if you need it, after you confirm the app is stateless.
  4. Set up start at boot with pm2 startup and pm2 save.
  5. Set up log rotation and watch the disk usage.
  6. Reboot the server once and see that everything comes back.

People often skip the last step. Yet the real assurance is that the app returns by itself after a real reboot. Do not call the setup finished until you see it.

As a result, the practical answer to what is PM2 is this: an operations layer that keeps your Node.js app alive, watched and easy to update. Set it up well and the site sees fewer outages. Skip it and you learn about it at the first crash.

Frequently Asked Questions

Is PM2 free and what is it for?
PM2 is an open source Node.js process manager, and you use its core features from the command line. It runs your app in the background, restarts it after a crash, gathers logs and offers cluster mode. Web based monitoring such as pm2 plus is separate. Check its terms on the official site, because the scope can change.
What is the difference between PM2 and nodemon?
nodemon restarts an app when files change while you develop. PM2 is built for live environments: it restarts crashed apps, manages logs, offers cluster mode and sets up start at boot. So nodemon on your laptop and PM2 or systemd on the server is a common split. Choose based on what your team already knows.
What is the difference between reload and restart?
According to the docs, restart stops the process at once and starts it again, so a short gap can appear. Reload renews processes one by one in cluster mode and aims for no downtime. In fork mode there is only one process, so test the behavior on a staging copy before you rely on it in production.
Why does my app not start after a server reboot?
Most likely pm2 startup or pm2 save is missing. The first command sets up the boot script, and the second saves the list of running apps. If you upgraded Node.js, the docs say to run pm2 unstartup and then pm2 startup. If that does not fix it, ask the person who runs your server.
Can I use systemd instead of PM2?
Yes, you can. Systemd comes with Linux, and the Restart setting in a service file restarts the app after a crash. However, it has no Node.js specific features such as cluster mode. A simple single process app may be fine with systemd alone. For several cores, consider PM2 cluster mode or another design.
Should I install PM2 myself or leave it to my hosting provider?
If you have full server access and some command line experience, try it on a staging copy first and install it yourself. On shared hosting without access, do not force it. Leave risky decisions such as firewalls, SSL, permissions and backups to your provider or an experienced administrator, and attach log samples to your request.
  • pm2
  • node.js
  • process manager
  • cluster mode
  • systemd
  • ecosystem file
  • log management
Share:
Talha Aslan

Google Partner digital marketing expert. Hands-on with SEO, Google Ads, web design and e-commerce projects since 2012; every post here comes from that experience.

Next project

Let's talk about your project.

Your brief goes straight to Talha Aslan and team: strategy led by Talha, delivery by an experienced team. The first consultation is free; we listen and come back with a clear roadmap.