How to make a task job with PM2?

I want to make a repeatable job to send mail every 15 minutes taking data from a database table. In node js I can create the job but through PM2 I don't understand where to place the code and how it works.


Use the --cron option:

-c --cron <cron_pattern>

For example:

pm2 start sendMail.js --cron "*/15 * * * *"

Pm2 will now restart the sendMail.js script on the hour, and at 15, 30 and 45 minutes past the hour


This is what worked for me, I split the cron in a different file which runs in a different process because i want to free up resources after cron has completed execution.

ecosystem.config.js:

module.exports = {
  /**
   * Application configuration section
   * http://pm2.keymetrics.io/docs/usage/application-declaration/
   */
  apps: [

    // Main API Hosting
    {
      name: 'API',
      script: 'bin/www',
      env: {
        COMMON_VARIABLE: 'true'
      },
      instances: 1,
      exec_mode: 'cluster',
      watch: false,
      autorestart: true
    },
    {
      name: 'CRON',
      script: "crons/cronjob.js",
      instances: 1,
      exec_mode: 'fork',
      cron_restart: "0,30 * * * *",
      watch: false,
      autorestart: false
    }
  ]
};

The following lines are important in the cron executable

cron_restart: "0,30 * * * *" <- cron expression

autorestart: false <- important because otherwise pm2 will restart the cron after completion immediately

Also make sure your instances is 1 otherwise multiple cron processes will run.

Key caveats:

Whenever you do pm2 restart all, the cron job will run irrespective of the cron expression. If Its critical to run only at specific times, add this additional check in the beginning of the cron file

if (new Date().getHours() !== 0 ) {
  console.log(`Current hours is ${new Date().getHours()}, not running.`)
  process.exit(0);
}

If you use PM2 ecosystem then in the config file add cron sequence to script param by wrapping it with single quotes. Somehow double quotes didn't work for me.

module.exports = {
  apps : [{
    name        : "Send-mail",
    script      : "./sendMail.js --cron '*/15 * * * *'",
    watch       : true
  }]
}

alternatively (my preference)

module.exports = {
  apps : [{
    name        : "Send-mail",
    script      : "./sendMail.js",
    cron_restart: "*/15 * * * *",
    watch       : true
  }]
}

If you execute the following command:

pm2 start handle-cron.js --cron "*/15 * * * *"

PM2 will initiate your cron job, but it will also continuously restart the cron-job after completion. --Infinite Loop

You want to set the instance to 1 and set no-autorestart.

pm2 start handle-cron.js --no-autorestart --instances 1  --cron "0 * * * *"