VOOZH about

URL: https://blog.logrocket.com/task-scheduling-or-cron-jobs-in-node-using-node-cron/

⇱ Scheduling tasks in Node.js using node-cron - LogRocket Blog


2024-11-12
1997
#node
Godwin Ekuma
22667
114
πŸ‘ Image

See how LogRocket's Galileo AI surfaces the most severe issues for you

No signup required

Check it out

Editor’s Note: This article was updated by Muhammed Ali on 12 November 2024 to include information on error handling, best practices, scheduling techniques, and practical use cases.

πŸ‘ Task Scheduling and cron Jobs in Node Using node-cron

No developer wants to spend all their time on tedious tasks such as system maintenance and administration, daily database backup, and downloading files and emails at regular intervals. You’d much rather focus on productive tasks instead of keeping track of when these bothersome chores need to get done.

And you’d certainly rather be asleep in your bed than up at some ungodly hour, staring bleary-eyed at a monitor as you run tasks that are best executed when server resources are being consumed at a lower rate.

That’s where task scheduling comes in.

Task scheduling enables you to schedule arbitrary code (methods/functions) and commands to be executed at a fixed date and time, at recurring intervals, or once after a specified interval. In Linux operating systems, task scheduling is often handled by utility services such as cron at the OS level. For Node.js apps, cron-like functionalities are implemented using packages such as node-cron, which bills itself as a β€œtiny task scheduler in pure JavaScript for Node.js.”

The actions of cron are driven by a crontab (cron table) file, a configuration file that contains instructions to the cron daemon. The node-cron module allows you to schedule tasks in Node using the full crontab syntax.

A crontab syntax looks like this:

# β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ second (optional)
 # β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ minute
 # β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ hour
 # β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€ day of month
 # β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€ month
 # β”‚ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€ day of week
 # β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
 # β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
 # * * * * * *

Allowed cron values include the following.

Field Value
second 0–59
minute 0–59
hour 0–23
day of the month 1–31
month 1–12 (or names)
day of the week 0–7 (or names, 0 or 7 are sunday)

πŸš€ Sign up for The Replay newsletter

The Replay is a weekly newsletter for dev and engineering leaders.

Delivered once a week, it's your curated guide to the most important conversations around frontend dev, emerging AI tools, and the state of modern software.

Using node-cron

In this section, you will learn how to use node-cron. Let’s start by installing it.

Install node-cron using npm.

npm install --save node-cron

Task scheduling syntax

Here you will learn what the general task scheduling syntax looks like and what each component stands for.

cron.schedule(cronExpression: string, task: Function, options: Object)

Options

Here are some other options that could be used in the syntax:

  • scheduled: A boolean to set if the created task is scheduled (default is true)
  • timezone: The timezone used for job scheduling

Take a look at the following example:

import * as cron from 'node-cron'
cron.schedule('5 * * * * *', () => {
 console.log('running a task every minute at the 5th second');
});

The asterisks (*) in positions, two, three, four, five, and six of the time specification are like file globs, or wildcards, for time divisions; they specify β€œevery minute,” β€œevery hour,” β€œevery day of the month,” β€œevery month,” and β€œevery day of the week,” respectively.

The following code would run every day at 5:03 a.m. (3 5):

import * as cron from 'node-cron'
cron.schedule('3 5 * * *', () => {
 console.log('running a task every day at 5:03 am');
});

Task scheduling tips and tricks

Now that we’ve got the basics covered, let’s do something more interesting.

Let’s say you want to run a particular task every Friday at 4 p.m. The code would look like this:

import * as cron from 'node-cron'
cron.schedule('0 16 * * friday', () => {
 console.log('running a task every Friday at 4:00 pm');
});

Or maybe you need to run quarterly database backups. The crontab syntax has no option for β€œthe last day of the month,” so instead you can use the first day of the following month, as shown below:

import * as cron from 'node-cron'
cron.schedule('2 3 1 1,4,7,10 *', () => {
 console.log('running a task every quater on the first day of the month');
});

The following shows a task that runs five minutes past every hour between 10:05 a.m. and 6:05 p.m.:

import * as cron from 'node-cron'
cron.schedule('5 10-18 * * *', () => {
 console.log('running a task five minutes past every hour between 10am and 6pm');
});

There may be situations where you need to run a task every two, three, or four hours. You can do so by dividing the hours by the desired interval, such as */4 for every four hours, or 0-12/3 to run every three hours between 12 a.m. and 12 p.m.

Minutes can be divided similarly. For example, the expression */10 in the minutes position means β€œrun the job every 10 minutes.”


Over 200k developers use LogRocket to create better digital experiences

πŸ‘ Image
Learn more β†’

The task below runs five minutes every two hours between 8 a.m. and 5:58 p.m.:

import * as cron from 'node-cron'
cron.schedule('*/5 8-18/2 * * *', () => {
 console.log('running a task every two hours between 8 a.m. and 5:58 p.m.');
});

Scheduled task methods

Let’s go over some key scheduled task methods.

Starting a task

When you set the scheduled option value to false, a task will be scheduled but cannot be started, even if the cron expression ticks.

To start such a task, you need to call the scheduled task start method:

const cron = require('node-cron');

import * as cron from 'node-cron'
const task = cron.schedule('*/5 8-18/2 * * *', () => {
 console.log('running a task every two hours between 8 a.m. and 5:58 p.m.');
});
task.start();

Dynamic scheduling

Update or modify scheduled tasks based on application state or real-time data:

let task = cron.schedule('*/5 * * * *', () => {

console.log('running every 5 minutes');

});

// Dynamically change the task based on application state

if (someCondition) {

task.setTime('*/10 * * * *'); // change to every 10 minutes

}

This snippet shows dynamic scheduling by first setting a task to run every five minutes. When a specific condition (someCondition) is met, the task’s schedule is changed to every 10 minutes using the setTime method. This can be useful for adjusting task frequency based on varying conditions.

Adjusting task frequency based on user activity

Imagine you have a Node.js application that tracks the number of active users. If the number of active users increases significantly, you might want to run a background task more frequently, such as sending real-time analytics to a monitoring service.

When user activity decreases, the task can run less often to conserve resources.

Here’s how to implement this using node-cron:

import * as cron from 'node-cron';

let activeUsers = 0; // Simulate active user count
let taskFrequency = '*/5 * * * *'; // Default frequency: every 5 minutes

// Function to update task frequency based on active user count
function updateTaskFrequency() {
 if (activeUsers > 1000) {
 taskFrequency = '*/1 * * * *'; // Run every minute if users exceed 1000
 } else if (activeUsers > 100) {
 taskFrequency = '*/3 * * * *'; // Run every 3 minutes if users exceed 100
 } else {
 taskFrequency = '*/5 * * * *'; // Default to every 5 minutes
 }
 console.log(`Task frequency updated: ${taskFrequency}`);
}

// Initial scheduling of the task
let task = cron.schedule(taskFrequency, () => {
 console.log(`Task running with ${activeUsers} active users`);
 // Code to send analytics data or perform other actions
});

// Example of how to simulate changing the number of active users and updating the task
setInterval(() => {
 activeUsers = Math.floor(Math.random() * 2000); // Simulate varying user counts
 updateTaskFrequency();
 task.stop(); // Stop the current task
 task = cron.schedule(taskFrequency, () => { // Re-schedule with new frequency
 console.log(`Task running with ${activeUsers} active users`);
 });
}, 60000); // Check and update frequency every minute

activeUsers simulates the number of online users, which could come from real-time data in a real application. updateTaskFrequency then adjusts the cron expression based on the active user count.

The task is re-scheduled whenever the frequency changes, ensuring it runs at the appropriate intervals based on current conditions.


More great articles from LogRocket:


Timezone management

Use the timezone option for global applications:

cron.schedule('0 16 * * *', () => {
 console.log('running a task at 4:00 PM UTC');
}, {
 timezone: 'America/New_York'
});

In this example, we schedule a task to run daily at 4:00 p.m., adjusting it to the timezone set by America/New_York. This flexibility is useful for applications with users in multiple timezones, allowing you to manage tasks based on local times.

Stopping a task

If a need to stop a task from running arises, you can use the scheduled task stop method to set the scheduled option to false. The task won’t be executed unless restarted:

const cron = require('node-cron');

import * as cron from 'node-cron'
const task = cron.schedule('*/5 8-18/2 * * *', () => {
 console.log('running a task every two hours between 8 a.m. and 5:58 p.m.');
});
task.stop();

Destroying a task

The destroy method stops a task and completely destroys it:

const cron = require('node-cron');

import * as cron from 'node-cron'
const task = cron.schedule('*/5 8-18/2 * * *', () => {
 console.log('running a task every two hours between 8 a.m. and 5:58 p.m.');
});
task.destroy();

Error handling and best practices

To ensure efficiency in your scheduled tasks, it’s important to incorporate error handling, logging, and retry mechanisms. Here’s an example of how to add error handling within a node-cron task:

cron.schedule('5 * * * *', () => {

try {

// Task code

} catch (error) {

console.error('Task failed:', error);

// Implement a retry mechanism or logging here

}

});

Wrapping the task code in a try...catch block allows you to catch any errors that occur during task execution. This example logs errors to the console and can include further retry mechanisms to handle failures gracefully.

Logging and retry mechanisms

Logging has to do with recording any errors and important events to make debugging easier.

For tasks that depend on network calls or external resources (e.g., API requests or file downloads), implementing a retry mechanism helps manage intermittent failures.

Building on the earlier example around adjusting task frequency based on user activity, we could add logging and retry mechanism as you see in the code below:

import * as cron from 'node-cron';

// Simulate active user count
let activeUsers = 0; 
let taskFrequency = '*/5 * * * *'; 
const maxRetries = 3; // Maximum number of retries for failed tasks

// Function to log messages
function logMessage(message) {
 const timestamp = new Date().toISOString();
 console.log(`[${timestamp}] ${message}`);
}

// Function to update task frequency based on active user count
function updateTaskFrequency() {
 if (activeUsers > 1000) {
 taskFrequency = '*/1 * * * *'; 
 } else if (activeUsers > 100) {
 taskFrequency = '*/3 * * * *'; 
 } else {
 taskFrequency = '*/5 * * * *'; 
 }
 logMessage(`Task frequency updated: ${taskFrequency}`);
}

// Function to execute the task with retry logic
async function executeTaskWithRetry(retries = 0) {
 try {
 logMessage(`Task running with ${activeUsers} active users`);
 // Simulated potential error (uncomment to test retry logic)
 // if (Math.random() < 0.2) throw new Error('Simulated task failure');

 } catch (error) {
 logMessage(`Error: ${error.message}. Attempt ${retries + 1} of ${maxRetries}`);


 if (retries < maxRetries) {
 // Retry the task after a short delay
 setTimeout(() => executeTaskWithRetry(retries + 1), 5000); // 5-second delay
 } else {
 logMessage(`Task failed after ${maxRetries} retries.`);
 }
 }
}

// Initial scheduling of the task
let task = cron.schedule(taskFrequency, () => {
 executeTaskWithRetry(); // Run the task with retry logic
});

// Example of how to simulate changing the number of active users and updating the task
setInterval(() => {
 activeUsers = Math.floor(Math.random() * 2000); // Simulate varying user counts
 updateTaskFrequency();


 task.stop(); // Stop the current task
 task = cron.schedule(taskFrequency, () => { // Re-schedule with new frequency
 executeTaskWithRetry(); // Run the task with retry logic
 });
}, 60000); // Check and update frequency every minute

Here, the logMessage function captures a timestamped log of each event or error. This provides a record of task executions, updates, and errors, making debugging easier.

The executeTaskWithRetry function wraps the task code in a try...catch block so that if an error occurs, the function logs the error and retries the task up to a maximum of maxRetries. Each retry is delayed by 5 seconds using setTimeout.

Practical use cases

node-cron has a wide range of applications in production environments. Here are a few real-world use cases:

Database backups

Regularly schedule database backups to ensure data safety and disaster recovery. For example:

cron.schedule('0 2 * * *', () => {
 console.log('Running a daily database backup at 2:00 AM');
});

This task runs every day at 2:00 a.m., a common time for backup tasks when server load is usually lower.

Email reminders

Set up periodic email reminders for users, such as weekly reminders:

cron.schedule('0 9 * * 1', () => {
 console.log('Sending a weekly email reminder every Monday at 9:00 AM');
});

Here, an email reminder task is scheduled to run every Monday at 9:00 a.m. This setup is useful for applications with time-sensitive notifications.

Conclusion

In this guide, we covered an in-depth look at how to create a cron job in Node.js using node-cron. From basic syntax and advanced techniques to practical applications and error handling, you now have the tools to implement effective and robust task scheduling in your Node.js applications.

200s only πŸ‘ Image
Monitor failed and slow network requests in production

Deploying a Node-based web app or website is the easy part. Making sure your Node instance continues to serve resources to your app is where things get tougher. If you’re interested in ensuring requests to the backend or third-party services are successful, try LogRocket.

πŸ‘ LogRocket Network Request Monitoring

LogRocket lets you replay user sessions, eliminating guesswork around why bugs happen by showing exactly what users experienced. It captures console logs, errors, network requests, and pixel-perfect DOM recordings β€” compatible with all frameworks.

LogRocket's Galileo AI watches sessions for you, instantly identifying and explaining user struggles with automated monitoring of your entire product experience.

LogRocket instruments your app to record baseline performance timings such as page load time, time to first byte, slow network requests, and also logs Redux, NgRx, and Vuex actions/state. Start monitoring for free.

πŸ‘ Image
πŸ‘ Image
πŸ‘ Image

Stop guessing about your digital experience with LogRocket

Get started for free

Recent posts:

I benchmarked Claude Code and OpenCode on a heavy refactor: The reality of agentic CLI workflows

Claude Code vs. OpenCode in a real Next.js refactor: benchmark results, mistakes, prompts, and when to use each CLI agent.

πŸ‘ Image
Chizaram Ken
May 28, 2026 β‹… 11 min read

The 5 Claude skills for React I can’t live without

Every time you explain your team’s coding standards to Claude, you are doing work that should be reusable. The same […]

πŸ‘ Image
Chizaram Ken
May 27, 2026 β‹… 10 min read

Stop trying to one-shot: How to prompt Claude better

Learn how to move beyond one-shot prompting in Claude with structured workflows for AI-assisted coding, debugging, PR reviews, documentation, testing, and automation.

πŸ‘ Image
Peter Aideloje
May 26, 2026 β‹… 18 min read

How to build advanced forms in Next.js using a rule engine

Learn how to build advanced Next.js forms with rule engines, client-side previews, Server Actions, and server-validated form logic.

πŸ‘ Image
Ikeh Akinyemi
May 21, 2026 β‹… 18 min read
View all posts

Would you be interested in joining LogRocket's developer community?

Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.

Sign up now