Facebook Pixel

Using PM2 cron-start for Recurring Tasks Server-Level Scheduling

Learn how to use PM2's cron-start feature to schedule Node.js scripts at the server level an alternative to node-cron for production deployments.

Using PM2 cron-start for Recurring Tasks

PM2 has built-in cron support that runs Node.js scripts at scheduled intervals. This is a server-level alternative to node-cron.

Why Use PM2 cron?

  1. Server-level Runs even if your main app is down
  2. PM2 managed Automatic restart on failure
  3. No extra dependencies Built into PM2
  4. Logs PM2 captures all output
  5. Simple No code changes needed

PM2 cron-start Syntax

# Run a script every day at midnight pm2 start scripts/cleanup.js --cron "0 0 * * *" --name daily-cleanup # Run every hour pm2 start scripts/stats.js --cron "0 * * * *" --name hourly-stats # Run every 15 minutes pm2 start scripts/health-check.js --cron "*/15 * * * *" --name health-check

PM2 Ecosystem File

// ecosystem.config.js module.exports = { apps: [ // Main API server { name: "devtinder-api", script: "src/server.js", instances: "max", exec_mode: "cluster" }, // Cron jobs { name: "daily-cleanup", script: "scripts/cleanup.js", cron: "0 0 * * *", autorestart: false // Don't restart after completion }, { name: "hourly-stats", script: "scripts/stats.js", cron: "0 * * * *", autorestart: false }, { name: "weekly-report", script: "scripts/weeklyReport.js", cron: "0 0 * * 1", // Every Monday at midnight autorestart: false } ] };
pm2 start ecosystem.config.js pm2 save

Creating Cron Scripts

// scripts/cleanup.js require("dotenv").config(); const mongoose = require("mongoose"); const User = require("../src/models/User"); const run = async () => { try { await mongoose.connect(process.env.MONGODB_URI); console.log("Connected to MongoDB"); // Delete expired tokens const result = await User.updateMany( { resetPasswordExpires: { $lt: new Date() } }, { $unset: { resetPasswordToken: 1, resetPasswordExpires: 1 } } ); console.log(`Cleaned up ${result.modifiedCount} users`); await mongoose.disconnect(); console.log("Done"); process.exit(0); } catch (err) { console.error("Cleanup failed:", err); process.exit(1); } }; run();

PM2 cron vs node-cron

FeaturePM2 cronnode-cron
Runs inSeparate processIn the main app
Survives app crashYesNo
LogsPM2 logsApp logs
DependenciesPM2 onlynode-cron package
ComplexitySeparate scriptInline in app
Best forIndependent tasksApp-integrated tasks

When to Use PM2 cron vs node-cron

Use PM2 cron for:

  • Database backups (independent of app)
  • Log rotation (server-level)
  • System health checks
  • Report generation (doesn't need app context)

Use node-cron for:

  • Tasks that need app state (cache, connections)
  • Tasks that use app models and utilities
  • Tasks that should stop when the app stops
  • Tasks that need the same database connection

Viewing PM2 Cron Jobs

# List all PM2 processes pm2 status # View logs of a specific cron job pm2 logs daily-cleanup # View logs of all cron jobs pm2 logs # Stop a cron job pm2 stop daily-cleanup # Restart a cron job pm2 restart daily-cleanup # Delete a cron job pm2 delete daily-cleanup

The Takeaway

PM2 cron-start runs Node.js scripts at scheduled intervals at the server level. Use it for independent tasks like backups, log rotation, and system health checks. Use node-cron for tasks integrated with your app (using models, cache, connections). Both use cron expressions. PM2 cron jobs are managed by PM2 (automatic restart, logs, monitoring) and run in separate processes.

Use pm2 start script.js --cron '0 0 * * *' --name task-name. Or define in ecosystem.config.js with cron: '0 0 * * *' and autorestart: false. PM2 runs the script at the scheduled time, captures logs, and manages restarts.

Use PM2 cron for independent tasks (backups, log rotation, system checks) that don't need app context. Use node-cron for tasks integrated with your app (using models, cache, database connections) that should stop when the app stops.

Create a standalone script that connects to the database, performs the task, and exits with process.exit(0) on success or process.exit(1) on failure. Load dotenv, connect to MongoDB, run the task, disconnect, and exit. PM2 will run it at the scheduled cron time.

Use pm2 logs task-name to view logs of a specific cron job. Use pm2 logs to view all logs. Use pm2 status to see all processes including cron jobs and their last execution status.

Yes. Cron jobs are one-time scripts that run and exit. Without autorestart: false, PM2 would restart the script immediately after it exits, causing it to run continuously instead of only at the scheduled cron time.

Ready to master Node.js completely?

Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course to dive deeper with high-quality video tutorials, solve interview questions, and a premium community.

Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.