How to correctly schedule a task using crontab, PM2 and NodeJS?

I currently have a schedule set up using crontab that runs a file every morning using PM2 with the below command:

10 07 * * * export NODE_ENV=prod&& sudo -E pm2 start /pathToFile/file.js -n fileName --no-autorestart

The issue here is that even when the script is complete, the pm2 process is still marked as “online” and still has memory allocated to it. After a while, the server slows down and i have to kill pm2 to get it working again.

I assumed it could be a memory leak but when i run the same command using node instead it exits correctly.

I also tried to used the below command to schedule the task directly inside PM2 (–no-autostart to avoid it starting immediately) but the script does not start at the expected time:

export NODE_ENV=prod&& sudo -E pm2 start ~/file.js -n fileName --cron "*/5 * * * *" --no-autostart

In this case PM2 Logs only show the following:

PM2        | 2025-06-18T08:10:00: PM2 log: [PM2] Deregistering a cron job on: 11
PM2        | 2025-06-18T08:10:00: PM2 log: [PM2][WORKER] Registering a cron job on: 11

How can i correct the above command(s) to get the file to:

  • Start and restart according to the cron schedule
  • Get PM2 to place the task/file in a “Stopped” state after the cron schedule has completed so that memory is released when the script is not running?

Best Solution: Use node (not pm2) in cron

Since your script exits cleanly with node, use this simple and effective crontab entry:

10 07 * * * NODE_ENV=prod /usr/bin/node /pathToFile/file.js >> /var/log/file.log 2>&1

This avoids memory leaks
No need for PM2
Script runs and exits cleanly
Output saved in log


Why your PM2 cron job failed

Your command:

pm2 start ~/file.js -n fileName --cron "*/5 * * * *" --no-autostart
  • --no-autostart prevents it from running even at the scheduled time.
  • PM2 expects persistent processes, so it won’t “stop” and free memory after each run.

If you must use PM2 (not recommended here):

  1. Start with --cron, without --no-autostart:
pm2 start /pathToFile/file.js -n fileName --cron "10 7 * * *" --no-autorestart
  1. Add this to your script to exit on finish:
process.on('exit', () => {
  console.log('Script completed');
});
process.exit(0);

But again, PM2 is not ideal for scheduled jobs that should fully exit.