Table of Contents
- What Are Cron Jobs in Node.js?
- Approaches to Cron Jobs in Node.js
- Using System-Level Cron Jobs
- Using
node-cron
npm Package - Advanced: Job Scheduling with
agenda
- Common Use Cases
- Troubleshooting
- Best Practices
1. What Are Cron Jobs in Node.js?
Cron jobs let you execute functions or scripts at specific intervals (e.g., every minute, hourly, daily). In Node.js, you can:
- Use system-level cron (via
crontab
). - Use in-process schedulers (npm packages like
node-cron
oragenda
).
2. Approaches to Cron Jobs in Node.js
Method | Pros | Cons |
---|---|---|
System Cron | Simple, OS-managed, survives app crashes | Requires shell access, harder to debug |
node-cron |
Easy in-app scheduling, JS syntax | Tied to app lifecycle (stops if app crashes) |
agenda |
Persistent jobs, retries, MongoDB support | Requires MongoDB, more complex setup |
3. Using System-Level Cron Jobs
Step 1: Create a Node.js Script
// scripts/cleanup.js
console.log('Cleaning up database at', new Date().toISOString());
// Add your logic here
Step 2: Make the Script Executable
chmod +x scripts/cleanup.js
Step 3: Schedule with Crontab
Edit your crontab:
crontab -e
Add a job (use the full path to Node.js and your script):
# Run every day at 2:30 AM
30 2 * * * /usr/local/bin/node /home/user/app/scripts/cleanup.js >> /var/log/cron.log 2>&1
Key Notes:
- Find your Node.js path with
which node
(e.g.,/usr/local/bin/node
). - Use absolute paths for scripts and output files.
- Log output to debug issues (
>> /var/log/cron.log 2>&1
).
4. Using node-cron
npm Package
Ideal for in-app scheduling without relying on system cron.
Installation
npm install node-cron
Basic Usage
const cron = require('node-cron');
// Run every minute
cron.schedule('* * * * *', () => {
console.log('Running task every minute:', new Date().toISOString());
});
Advanced Example (with Timezone)
const cron = require('node-cron');
// Run daily at 8:00 AM in Europe/London timezone
cron.schedule('0 8 * * *', () => {
console.log('Sending morning report...');
}, {
scheduled: true,
timezone: 'Europe/London'
});
Schedule Syntax Cheatsheet
Pattern | Description |
---|---|
*/5 * * * * |
Every 5 minutes |
0 9 * * 1-5 |
Weekdays at 9:00 AM |
0 0 1 * * |
First day of the month at midnight |
5. Advanced: Job Scheduling with agenda
For persistent, retriable jobs (requires MongoDB).
Installation
npm install agenda
Setup
const Agenda = require('agenda');
const agenda = new Agenda({ db: { address: 'mongodb://localhost:27017/agenda' } });
// Define a job
agenda.define('send-email', async (job) => {
const { userId } = job.attrs.data;
console.log(`Sending email to user ${userId}`);
// Add your email logic here
});
// Schedule job to run every 2 hours
agenda.every('2 hours', 'send-email', { userId: 123 });
// Start agenda
(async () => {
await agenda.start();
})();
Key Features:
- Persistent jobs: Survive app restarts.
- Retries: Automatically retry failed jobs.
- Flexible scheduling: Use cron syntax or human-readable intervals.
6. Common Use Cases
1. Database Cleanup (Expired Tokens)
// Using node-cron
cron.schedule('0 0 * * *', async () => {
await Token.deleteMany({ expiresAt: { $lt: new Date() } });
});
2. Send Daily Reports via Email
// Using agenda
agenda.define('daily-report', async () => {
const users = await User.find({ wantsReport: true });
users.forEach(user => sendEmail(user.email, 'Your daily report!'));
});
agenda.every('0 9 * * *', 'daily-report');
3. Cache Invalidation
// Every 10 minutes
cron.schedule('*/10 * * * *', () => {
cache.clearExpired();
});
4. Poll External APIs
// Poll every 5 minutes
cron.schedule('*/5 * * * *', async () => {
const data = await fetch('https://api.example.com/data');
await processData(data);
});
7. Troubleshooting
Common Issues & Fixes:
-
Cron job not running:
- Check if the Node process is running (for
node-cron
/agenda
). - For system cron, check logs:
grep CRON /var/log/syslog
.
- Check if the Node process is running (for
-
Module not found:
- Use absolute paths in scripts.
- Install dependencies globally if needed (not recommended).
-
Permissions issues:
- Ensure the cron user has execute access:
chmod +x your-script.js
.
- Ensure the cron user has execute access:
-
Timezone mismatches:
- Use the
timezone
option innode-cron
or setTZ
in your OS.
- Use the
Debugging Tips:
- Log everything:
cron.schedule('* * * * *', () => {
console.log('Cron job started at', new Date());
try {
// Your logic here
} catch (err) {
console.error('Cron job failed:', err);
}
});
- Test with shorter intervals first (e.g., every minute).
8. Best Practices
1. Use Task Queues for Heavy Work
Offload CPU-heavy tasks to worker threads:
const { Worker } = require('worker_threads');
cron.schedule('0 * * * *', () => {
const worker = new Worker('./path/to/worker.js');
});
2. Handle Failures Gracefully
// With agenda (automatic retries)
agenda.define('critical-job', { concurrency: 1, maxAttempts: 3 }, async (job) => {
// Your logic
});
// With node-cron
cron.schedule('...', async () => {
try {
await criticalTask();
} catch (err) {
sendAlertToSlack('Cron job failed: ' + err.message);
}
});
3. Avoid Overlapping Jobs
Use agenda
’s concurrency control or a locking mechanism:
let isJobRunning = false;
cron.schedule('*/5 * * * *', async () => {
if (isJobRunning) return;
isJobRunning = true;
await longRunningTask();
isJobRunning = false;
});
4. Use Environment-Specific Schedules
Disable cron jobs in development:
// In your Node.js app
if (process.env.NODE_ENV === 'production') {
cron.schedule('...', productionTask);
}
5. Monitor Your Jobs
- Log job start/end times.
- Use tools like PM2 for process management:
pm2 start app.js
pm2 logs
Final Thoughts
Choose system cron if:
- You need tasks to run independently of your Node app.
- Your hosting provider supports
crontab
.
Choose node-cron
if:
- You prefer keeping jobs within your codebase.
- You need simple in-app scheduling.
Choose agenda
if:
- You require job persistence and retries.
- Your app already uses MongoDB.
By combining these tools with proper error handling and monitoring, you can build robust automated workflows for your Node.js backend. Happy coding! 🚀
Further Resources:
Author: Mohin Sheikh
Follow me on GitHub for more insights!
Top comments (0)