Tutorial
How To Use node-cron to Run Scheduled Jobs in Node.js
Introduction
cron
provides a way to repeat a task at a specific time interval. There may be repetitive tasks such as logging and performing backups that need to occur on a daily or weekly basis.
One method for implementing cron
on a Node.js server is by using the node-cron
module. This library uses the crontab
syntax, which may be familiar to users with previous experience with using cron
in Unix-like operating systems.
In this article, you will build a small application that periodically deletes log files from the server. You will also be presented with two other use cases - backing up a database and sending scheduled emails.
Prerequisites
To follow through this tutorial, you’ll need:
- A local development environment for Node.js. Follow How to Install Node.js and Create a Local Development Environment.
This tutorial was verified with Node v14.2.0, npm
v6.14.5, express
v4.17.1, and node-cron
v2.0.3.
Step 1 — Creating a Node Application and Installing Dependencies
To get started, create a new Node application by opening your terminal and creating a new folder for your project:
- mkdir cron-jobs-node
Next, change into the new project directory:
- cd cron-jobs-node
Then initialize it, which creates a package.json
file which you will use to track dependencies:
- npm init -y
Add the express
web framework and node-cron
module by running the following command:
- npm install express@4.17.1 node-cron@2.0.3
The express
module powers the webserver you will build. The node-cron
module is the task scheduler.
The project dependencies are installed. Let’s build the server.
Step 2 — Building the Backend Server and Scheduling a Task
Now, you can build the server and use node-cron
to schedule a task to run every minute.
Create an index.js
file:
- nano index.js
Then, require node-cron
and express
:
const cron = require('node-cron');
const express = require('express');
And create an instance of Express:
// ...
app = express();
app.listen(3000);
Next, add the following lines of code to your index.js
file between the app
declaration and app.listen
:
// ...
app = express();
// Schedule tasks to be run on the server.
cron.schedule('* * * * *', function() {
console.log('running a task every minute');
});
app.listen(3000);
These asterisks are part of the crontab
syntax to represent different units of time:
* * * * * *
| | | | | |
| | | | | day of week
| | | | month
| | | day of month
| | hour
| minute
second ( optional )
A single asterisk behaves like a wildcard. Meaning the task should be run should for every instance of that unit of time. Five asterisks ('* * * * *'
) represents the crontab
default of running every minute.
Numbers in the place of asterisks will be treated as values for that unit of time. Allowing you to schedule tasks to occur daily and weekly or in more complex
Learn more about how this notation works in How To Use Cron to Automate Tasks on a VPS.
Now, run the server:
- node index.js
You will get the following result:
Outputrunning a task every minute
running a task every minute
running a task every minute
...
You have an example task running every minute. You can stop the server with CTRL+C
.
Now, let’s look at how to run tasks in more detail.
Step 3 — Deleting an Error Log
Consider a scenario where you need to routinely delete the log file from the server on the twenty-first day of every month. You can accomplish this with node-cron
.
Create an example log file named error.log
:
- nano error.log
Then, add a test message:
This is an example error message that should be removed on the twenty-first day of the month.
Next, revisit index.js
:
- nano index.js
This task will use fs
to unlink
a file. Add it to the top of the file:
const cron = require('node-cron');
const express = require('express');
const fs = require('fs');
Then, comment out or delete your previous example task:
// ...
// Schedule tasks to be run on the server.
// cron.schedule('* * * * *', function() {
// console.log('running a task every minute');
// });
app.listen(3000);
Next, add the following lines of code:
// ...
// Remove the error.log file every twenty-first day of the month.
cron.schedule('0 0 21 * *', function() {
console.log('---------------------');
console.log('Running Cron Job');
fs.unlink('./error.log', err => {
if (err) throw err;
console.log('Error file successfully deleted');
});
});
app.listen(3000);
Notice the pattern: 0 0 21 * *
.
- It defines a value for minutes and hours as
0
and0
(“00:00” - the start of the day). - It defines a value for day as
21
. - It does not define a month or day of the week.
Now, run the server:
- node index.js
On the twenty-first of the month, you will get the following output:
Output---------------------
Running Cron Job
Error file successfully deleted
You probably do not want to wait for the twenty-first of the month to verify the task has been executed. You can modify the scheduler to run in a shorter time interval.
Check your server directory. The error.log
file should be deleted.
You can run any actions inside the scheduler. Actions ranging from creating a file to sending emails and running scripts. Let’s take a look at more use cases.
Step 4 — Exploring Using node-cron
to Back Up Databases
Ensuring the preservation of user data is very key to any business. If an unforeseen event happens and your database becomes corrupted or damaged, you will need to restore your database from a backup. You will be in serious trouble if you do not have any form of existing backup for your business.
Consider a scenario where you need to routinely back up a dump of the database at 11:59 PM every day. You can accomplish this with node-cron
.
Note: This use case entails setting up a local database. As this is outside the scope of this article, the finer details of the installation and set-up process are not discussed.
Assume that you have SQLite installed and running on your environment. Your shell command for making a database backup may resemble this:
- sqlite3 database.sqlite .dump > data_dump.sql
This command takes the database, database.sqlite
, and runs the .dump
command, and outputs the result as a file named data_dump.sql
Next, install shelljs
, a Node module that will allow you to run the previous shell command:
- npm install shelljs@0.8.4
Next, revisit index.js
:
- nano index.js
Then, require shelljs
:
const cron = require('node-cron');
const express = require('express');
const fs = require('fs'); // previous example
const shell = require('shelljs');
Next, add the following lines of code:
// ...
// Backup a database at 11:59 PM every day.
cron.schedule('59 23 * * *', function() {
console.log('---------------------');
console.log('Running Cron Job');
if (shell.exec('sqlite3 database.sqlite .dump > data_dump.sql').code !== 0) {
shell.exit(1);
}
else {
shell.echo('Database backup complete');
}
});
app.listen(3000);
Notice the pattern: 59 23 * * *
.
- It defines a value for minute as
59
. - It defines a value for hour as
23
(or11 PM
in a 24-hour clock). - It does not define a day, a month, or day of the week.
This code will run the backup shell command. If there is an error, it will exit. If it is successful, it will echo a message.
Now, run the server:
- node index.js
At 11:59 PM, you will get the following output:
Output---------------------
Running Cron Job
Database backup complete
You probably do not want to wait for 11:59 PM to verify the task has been executed. You can modify the scheduler to run in a shorter time interval.
Check your server directory. A data_dump.sql
file should be present.
Next, let’s look at sending periodic emails.
Step 5 — Exploring Using node-cron
to Send Scheduled Emails
Consider a scenario where you curate a list of interesting links and then email them to subscribers every Wednesday. You can accomplish this with node-cron
.
You will need an email account from one of the supported SMTP service.
Warning: It highly recommend to avoid using your personal email account for this step. Quick solutions on the internet may guide you towards lowering security measures. Consider using a new separate developer account to avoid any risk to your personal email account.
Next, install nodemailer
, a Node module that will allow you to send emails:
- npm install nodemailer@6.4.11
Next, revisit index.js
:
nano index.js
Then, require nodemailer
:
const cron = require('node-cron');
const express = require('express');
const fs = require('fs'); // previous example
const shell = require('shelljs'); // previous example
const nodemailer = require('nodemailer');
Add a section that defines the mailer and sets the username and password for an email account:
// ...
// Create mail transporter.
let transporter = nodemailer.createTransport({
host: 'your_demo_email_smtp_host.example.com',
port: your_demo_email_port,
secure: true,
auth: {
user: 'your_demo_email_address@example.com',
pass: 'your_demo_email_password'<^>
}
});
app.listen(3000);
Warning: This step is presented for example purposes only. In a production environment, you would use environment variables to keep your password a secret. Do not save your password (credentials) in any code you are uploading to code repositories like GitHub.
Next, add the following lines of code:
// ...
// Sending emails every Wednesday.
cron.schedule('0 0 * * 3', function() {
console.log('---------------------');
console.log('Running Cron Job');
let messageOptions = {
from: 'your_demo_email_address@example.com',
to: 'user@example.com',
subject: 'Scheduled Email',
text: 'Hi there. This email was automatically sent by us.'
};
transporter.sendMail(messageOptions, function(error, info) {
if (error) {
throw error;
} else {
console.log('Email successfully sent!');
}
});
});
app.listen(3000);
Notice the pattern: 0 0 * * 3
.
- It defines a value for minutes and hours as
0
and0
(“00:00” - the start of the day). - It does not define a day of the month or a month.
- It defines a value for day of the week as
'3'
(Wednesday).
This code will use the credentials provided to send an email from your_demo_email_address@example.com
to user@example.com
. With the subject line: 'Scheduled Email'
and the body text: 'Hi there. This email was automatically sent by us.'
. Or log an error if it fails.
Now, run the server:
- node index.js
On Wednesday, you will get the following output:
Output---------------------
Running Cron Job
Email successfully sent!
You probably do not want to wait for Wednesday to verify the task has been executed. You can modify the scheduler to run in a shorter time interval.
Check your recipient’s email. There should be a new 'Scheduled Email'
in the inbox.
Conclusion
In this article, you learned how to use node-cron
to schedule jobs on a Node.js server.
You were introduced to the broader concept of automating repetitive tasks in a consistent and predictable manner. This concept can be applied to your current and future projects.
There are other task scheduler tools available. Be sure to evaluate them to identify which tool is best suited for your particular project.
If you’d like to learn more about Node.js, check out our Node.js topic page for exercises and programming projects.