DEV Community

Cover image for Cron Jobs in Nest JS
Jayant
Jayant

Posted on

Cron Jobs in Nest JS

Cron Jobs are scheduled Tasks that runs automatically at a specified time.
They are commonly used for these works.

  • Running Backups at MIDNIGHT
  • Sending Email Reports

They use Cron Expressions that defines when the job should run.

// Format - they are either 5 or 6 fields
*     *     *     *     *     *
                         
                         └─ Day of Week (0 - 6) (Sunday to Saturday)
                    └────── Month (1 - 12)
               └──────────── Day of Month (1 - 31)
          └────────────────── Hour (0 - 23)
     └──────────────────────── Minute (0 - 59)
└────────────────────────────── (optional) Seconds (0 - 59)

Enter fullscreen mode Exit fullscreen mode

To make a Cron Expression you can go to Cron Tab Guru.

* * * * * *  - RUNS EVERY Seconds

* * * * * 1 - RUNS EVERY Second on Monday

0 1 * * * 1 - RUNS at past midnight every Monday

0 */1 * * * 1  - RUNS every 1 minute on Monday
Enter fullscreen mode Exit fullscreen mode

we don't need to memorize them, we can use Corn Expression Enums to make it easier.

How & Where to Run it

we can run it in our server or we can use serverless Cron Jobs provided by Cloud Providers.

To Run Cron Job in Node.js

// In Express
// Install the `node-cron` package
import cron from 'node-cron';

cron.schedule('0 0 * * *', () => {
  console.log('Running task at midnight');
});

//  In NestJS
// install @nestjs/schedule package


// Inside app.module register your Schedule Module, it initialize and registers any cron job in our app,

import { Module } from '@nestjs/common';
import { ScheduleModule } from '@nestjs/schedule';

@Module({
  imports: [
    ScheduleModule.forRoot()
  ],
})
export class AppModule {}


// To create a Cron JOb we need to attach @Cron() decorator to the handler
//  Using CronExpressionEnums
import { Injectable, Logger } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';

@Injectable()
export class TasksService {
  private readonly logger = new Logger(TasksService.name);

  @Cron(CronExpression.EVERY_30_SECONDS)
  handleCron() {
    this.logger.debug('Called every 30 seconds');
  }
}


//  If any exception occurs it will be logged in the console, as every method annoted with @Cron is automatically wrapped in try-catch block.
// We can also gives additional options to the @Cron decorator
import { Injectable, Logger } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';

@Injectable()
export class TasksService {
  private readonly logger = new Logger(TasksService.name);

  @Cron(CronExpression.EVERY_30_SECONDS, {
    name: 'my-cron-job',
    timeZone: 'Asia/Kolkata',
  })
  handleCron() {
    this.logger.debug('Called every 30 seconds');
  }
}
Enter fullscreen mode Exit fullscreen mode

In NestJS we can access the cron job once it is declared & also create it dynamically.

If we want to control a cron job we should give it a name.

To access & dynamically create the cron job using SchedulerRegistry.


const job = this.schedulerRegistry.getCronJob('notifications');

job.stop();
console.log(job.lastDate());
Enter fullscreen mode Exit fullscreen mode

We can also add a cron job dynamically.

addCronJob(name: string, seconds: string) {
  const job = new CronJob(`${seconds} * * * * *`, () => {
    this.logger.warn(`time (${seconds}) for job ${name} to run!`);
  });

  this.schedulerRegistry.addCronJob(name, job);
  job.start();

  this.logger.warn(
    `job ${name} added for each minute at ${seconds} seconds!`,
  );
}
Enter fullscreen mode Exit fullscreen mode

Cron Jobs can be both async and sync, Also they are used to run specific task at specific time.
If we want to run some task , Every X milliseconds like Polling, health checks, repeated tasks. Then we can use @Interval.

// similar to setInterval in nodejs
@Interval(10000) // Every 10 seconds
handleInterval() {
  console.log('Polling external service...');
}
Enter fullscreen mode Exit fullscreen mode

Also we have Timeout similar to setTimeout, they are used when we want to run a task once but after a delay.

  • Running a task once after app startup

  • Delaying execution of a retry or follow-up task

  • Debouncing logic (in rare backend scenarios)

@Timeout(5000) // After 5 seconds
handleTimeout() {
  console.log('Initial sync task after startup delay');
}
Enter fullscreen mode Exit fullscreen mode

They both can be called dynamically using SchedulerRegistry.

if you have set Cron Job to run EVERY_10_MINUTE, then it will run in every multiple of 10.

Top comments (0)