← Back to Blog
DevOps & Systems

How to Configure Custom Log Rotation for PM2 to Prevent VPS Disk Storage Bloat

By JustinPublished September 25, 202639 views
How to Configure Custom Log Rotation for PM2 to Prevent VPS Disk Storage Bloat

I run several Node.js apps under PM2 on one droplet, and each one prints a steady stream of output — cron job results, scrape logs, request errors. What I didn't appreciate until it actually caused a problem: PM2 does not rotate its log files by default. It appends to the same file forever, for as long as the process runs, with no size cap and no cleanup. On a server that's been up for months with several apps logging continuously, that adds up to real disk usage you won't notice until something else fails because of it.

How This Actually Bites You

PM2 writes each app's stdout and stderr to separate files under ~/.pm2/logs/, named after the app — myapp-out.log and myapp-error.log. Every single line the process prints goes into that file, appended forever, with nothing built in to cap the size or clean up old entries.

The failure mode isn't dramatic until suddenly it is: disk usage climbs slowly and invisibly for weeks or months, then something unrelated fails — a database write, a new deployment, a temp file write — because the disk is actually full. At that point you're debugging a confusing downstream failure instead of the actual root cause, which is a handful of log files nobody was watching.

Checking whether this is already a problem takes one command:

bash
du -sh ~/.pm2/logs/* | sort -rh | head -10

This lists your PM2 log files sorted largest first. If anything here is measured in hundreds of megabytes or more, unrotated logging is already costing you real disk space.

Unrotated PM2 application logs gradually consuming VPS disk space

The Fix: pm2-logrotate

PM2 has an official module for this — pm2-logrotate — that handles size-based rotation, compression of old logs, and automatic pruning of anything past a retention limit. It's not enabled by default; it has to be installed explicitly:

bash
pm2 install pm2-logrotate

Once installed, it runs as its own PM2-managed module and applies to every app PM2 manages on that server — you don't configure it per-app, it's a global policy across all your processes.

Configuring It Properly

The defaults are reasonable but worth tuning for your actual situation rather than leaving untouched. Here's the configuration I run, with what each setting actually does:

bash
# Rotate once a log file hits this size
pm2 set pm2-logrotate:max_size 10M

# Keep this many rotated (old) log files before deleting the oldest
pm2 set pm2-logrotate:retain 7

# Compress rotated logs with gzip instead of keeping them as plain text
pm2 set pm2-logrotate:compress true

# How often to check whether rotation is needed
pm2 set pm2-logrotate:workerInterval 30

# Also rotate on a time-based schedule, not just size
pm2 set pm2-logrotate:rotateInterval '0 0 * * *'

# Timestamp format used in rotated file names
pm2 set pm2-logrotate:dateFormat 'YYYY-MM-DD_HH-mm-ss'

How pm2-logrotate rotates, compresses, and retains PM2 application logs based on size and time

A few of these are worth explaining rather than just copying blindly:

max_size is the primary control — once any single log file crosses this size, it gets rotated (renamed, and a fresh file started). 10M is a reasonable default for a low-to-moderate traffic app; a noisier app (heavy scrape/cron logging, for instance) might warrant a smaller cap so rotation happens more frequently rather than letting one file grow large between rotations.

retain controls how many old, rotated files stick around before the oldest gets deleted entirely. This is your actual disk-usage ceiling in combination with maxsize — retain: 7 with maxsize: 10M means, roughly, each app's logs are bounded to somewhere around 70MB total across current and retained files, not unlimited.

compress matters more than it might seem — gzip typically shrinks log text substantially, so enabling this meaningfully reduces how much disk your retained history actually consumes for the same retain count.

rotateInterval adds a time-based trigger alongside the size-based one — useful because a low-traffic app might never hit max_size naturally, and you may still want daily rotation regardless of size, so log files stay organized by day even for quiet apps.

Verifying It's Actually Working

After configuring, don't just assume it's applied correctly — check the module's own status and confirm settings landed as expected:

bash
pm2 show pm2-logrotate

This shows the module's current configuration values, which is worth checking against what you actually set — a typo in a pm2 set command fails silently rather than throwing an error you'd notice.

Genuinely confirming rotation works means letting it run and checking back:

bash
ls -la ~/.pm2/logs/

After enough time (or enough log volume) to trigger a rotation, you should see rotated, timestamped, gzip-compressed files alongside the active log — that's the module working as intended.

What If the Disk Is Already Full?

Installing pm2-logrotate fixes the problem going forward; it doesn't retroactively shrink log files that already grew large before you set it up. If disk space is already a live problem, the fastest path back to a working server is to truncate the existing oversized files directly, without deleting them (which could disrupt a process that has the file open):

bash
# truncates in place, the process keeps its open file handle
truncate -s 0 ~/.pm2/logs/myapp-out.log

This empties the file immediately without touching the running process, buying you disk space back right away while pm2-logrotate handles keeping it from happening again.

PM2 log recovery and verification workflow for freeing disk space and enabling automatic log rotation

Frequently Asked Questions

Does pm2-logrotate affect application logs written outside of PM2's stdout/stderr capture?

No — this only rotates the files PM2 itself manages, which is whatever your app writes to stdout/stderr. If your application writes its own separate log files directly to disk (via a logging library writing to its own path), those need their own rotation setup — logrotate (the standard Linux utility, separate from PM2's module) handles that case well.

Will rotating logs lose data I might need for debugging later?

Rotation renames and eventually deletes old files past your retain count, so yes, sufficiently old logs are genuinely gone once they age out. Set retain based on how far back you realistically need to look when debugging something — for most personal or small-project use, a week or two of retained history is enough; a compliance or audit requirement would need much longer retention and possibly shipping logs somewhere external entirely.

Is 10M the right max_size for every app?

No — it depends entirely on how much your specific app actually logs. A quiet app that logs a few lines a day will rarely hit 10M regardless of the setting; a noisy one (verbose request logging, frequent cron output) might benefit from a smaller cap so rotation happens more often and no single file gets unwieldy between rotations.

Should I be shipping logs somewhere off the server instead of just rotating them locally?

For a small personal or small-business setup, local rotation with reasonable retention is often sufficient. Shipping logs to an external service becomes more worth the added complexity once you need centralized searching across multiple servers, longer retention than local disk can reasonably hold, or alerting based on log content rather than just keeping history around for manual review.

Tags:PM2loggingVPSdisk spaceNode.jsserver maintenance

Justin is a self-taught developer who builds and runs DeelCart himself — from the articles to the server it runs on. He manages his own Linux infrastructure and writes guides based on tools and workflows he actually uses day to day.

✍️ More Guides on DeelCart

Read more of our shopping and learning guides.

Browse the Blog →