How to create and run cron jobs in Node

How to create and run cron jobs in Node

You ever want to automate certain tasks on your app, saving you the hustle of doing them manually such as deletion of log files, automated emails or maybe doing a backup of your database data into a MongoDB/SQL dump file, well say no more cron jobs are here to help.

What is a cronjob?

A cron job is a task that automatically runs on a set schedule, example at 0000h you might have a cron job clear site cache on your CDN(Content Delivery Network).

By the end of this tutorial, you should be able to create a simple Node cron job.

Prerequisites

To get started with this tutorial you must have:

  • NodeJS installed on your development computer
  • Yarn or NPM installed
  • Knowledge in writing es5 Javascript

Getting Started

Setup

To have our cron job running we need to set up our Node project.

// Create our folder and change our directory to where it is created
$ mkdir cron_jobs_with_nodejs && cd cron_jobs_with_nodejs
// Initialize our package.json file
$ yarn init -y or npm init -y

We are going to create a simple cron job that deletes a file after a minute. Let's create a file to house our code

$ touch index.js

We need to install certain packages that will ensure we have a cron job

$ npm install express node-cron fs
  • express: For our cron job to run after a set time we need to initialize a keep-alive connection, which express library will offer when we initialize a HTTP server. You can still use Node inbuilt HTTP library.

    Note: We need to have a running program so that our cron job runs, thus the need for a HTTP connection.

  • node-cron: This is the library that will enable us to run our cron job successfully.
  • fs: Helps us access the file-system quite well. It comes built-in Node, so there is no need to install it.

Code

The boring but important step is over, now to the good stuff, code. Open index.js with your local editor.

First, we will have to set up our whole express server

// Import needed libraries
const express = require("express");
const Cron = require("node-cron");
const fs = require("fs");

// Initialize express
const app = express();

// Set  our default port
app.set("port", process.env.PORT || 3456);

// Initialize our server
app.listen(app.get("port"), err => {
  // If something goes wrong when initializing the server
  if (err) console.log(`Server failure due to ${err.message}`);
  console.log(`Server running on port ${app.get("port")}`);
});

Run our server.

$ node src/index.js

If successful you will see a similar message printed on your console/terminal.

Server running on port 3456

Secondly, we will write a simple cron job that console logs a statement after every minute.

// Import needed libraries
const express = require("express");
const Cron = require("node-cron");
const fs = require("fs");

// Initialize express
const app = express();

// Set  our default port
app.set("port", process.env.PORT || 3456);

// Schedule a cron job task
Cron.schedule("* * * * * ", () => {
  console.log("> After every minute the cron job runs");
});

// Initialize our server
app.listen(app.get("port"), err => {
  // If something goes wrong when initializing the server
  if (err) console.log(`Server failure due to ${err.message}`);
  console.log(`Server running on port ${app.get("port")}`);
});

You must be wondering about the weird value as the first argument for the Cron.schedule method. The value is how we set the intervals that the cron job should run.

Cron Syntax

* * * * * *
| | | | | |
| | | | | day of week
| | | | month
| | | day of month
| | hour
| minute
second ( optional )

Allowed values

Field TypeValue
Second0-59
minute0-59
hour0-23
day of month1-31
month1-12 or names i.e. January
day of week0-7 or names i.e. Monday

Using multiple values

You can use multiple values using separate commas

// Import needed libraries
const express = require("express");
const Cron = require("node-cron");
const fs = require("fs");

// Initialize express
const app = express();

// Set  our default port
app.set("port", process.env.PORT || 3456);

// Schedule a cron job task
Cron.schedule("1,2,4,5 * * * *", () => {
    console.log("> After every minute 1, 2, 4 and 5 the cron job runs")
})

// Initialize our server
app.listen(app.get("port"), err => {
  // If something goes wrong when initializing the server
  if (err) console.log(`Server failure due to ${err.message}`);
  console.log(`Server running on port ${app.get("port")}`);
});

Using ranges

// Import needed libraries
const express = require("express");
const Cron = require("node-cron");
const fs = require("fs");

// Initialize express
const app = express();

// Set  our default port
app.set("port", process.env.PORT || 3456);

// Schedule a cron job task
Cron.schedule("1-5 * * * *", () => {
    console.log("> After every minute to 1 from 5 the cron job runs")
})

// Initialize our server
app.listen(app.get("port"), err => {
  // If something goes wrong when initializing the server
  if (err) console.log(`Server failure due to ${err.message}`);
  console.log(`Server running on port ${app.get("port")}`);
});

You can use month names as multiple values in full or short format, January, February, September or Jan, Feb, Sep.

Let's create a cron job schedule that deletes a file after the first minute

$ touch tobedeletedfile.txt
// Import needed libraries
const express = require("express");
const Cron = require("node-cron");
const fs = require("fs");

// Initialize express
const app = express();

// Set  our default port
app.set("port", process.env.PORT || 3456);

/**
 * Cron job that deletes a file after every minute
 */

const deleteFileCron = Cron.schedule("* * * * *", () => {
  console.log("Job has started");
  fs.unlink("./tobedeletedfile.txt", err => {
    if (err) {
      console.log(`Failed to delete file due to ${err.message}`);
    } else {
      console.log("File has been deleted successfully");
    }
  });
});

// Its a scheduled task method that starts a scheduled task
deleteFileCron.start()

// Initialize our server
app.listen(app.get("port"), err => {
  // If something goes wrong when initializing the server
  if (err) console.log(`Server failure due to ${err.message}`);
  console.log(`Server running on port ${app.get("port")}`);
});

If you run the code you should something similar in your console/terminal

Server running on port 3456
Job has started
File has been deleted successfully
Job has started
Failed to delete file due to ENOENT: no such file or directory, unlink './tobedeletedfile.txt'

Simple Node Cron Job template

[...]
const Cron = require("node-cron");

[...]

Cron.schedule("* * * * *", () => {
    // You can right the task to run here
});

[...]

Advantages of Cron jobs over infinite loops

Some developers use infinite loops instead of cron jobs, this should not be the case because loops tend to occupy a lot of memory in your system compared to cron jobs.

Advantages of cron jobs

  • You have control over it when it runs.
  • It's easier to write the code and to manage its operation. It eliminates the looping and timing logic in the task, and you run crontab to change the timing or shut it off.
  • It's not occupying memory in your system when it's not running.
  • If it fails and exits for some reason, it will start up again when the proper time comes.

Advantages of loops

  • It doesn't have the overhead of being restarted every time it's needed

Where to use Cron jobs

You can use cron job in so many scenarios such as:

  • Email automation
  • Database backups
  • Deletion of files such as logs

Summary

  • We set up a simple cron job with Node that lets us delete a file after every minute.
  • Brief description of cron's syntax
  • Advantages of cron jobs
  • Where to use cron jobs

Resources and Recommendations

Below is a list of links, you can read up on to have a deep understanding of cron jobs in Node and general info about crons:

  • Cron job examples by CodeBeast here
  • node-cron documentation on npm here
  • Cron jobs with Node by Useful Angle here
  • All about crons, crontabs and cron jobs here

Extras

Cover image made by https://liyasthomas.github.io/banner/