Cron, Intervals & Timeouts — Declared
Scheduled Tasks
@nestjs/schedule lets you annotate methods with @Cron, @Interval, or @Timeout — no external scheduler required.
What you'll learn
- Install @nestjs/schedule and register ScheduleModule.forRoot
- Use @Cron, @Interval, and @Timeout decorators
- Manage dynamic schedules through SchedulerRegistry
For periodic in-process work — nightly cleanups, hourly metrics, polling
external APIs — @nestjs/schedule is the simplest tool that gets the job
done. It is a thin wrapper around cron and node timers, but DI-friendly.
Setup
npm i @nestjs/schedule import { Module } from '@nestjs/common';
import { ScheduleModule } from '@nestjs/schedule';
@Module({
imports: [ScheduleModule.forRoot()],
})
export class AppModule {} Cron, Interval, Timeout
import { Injectable, Logger } from '@nestjs/common';
import { Cron, Interval, Timeout } from '@nestjs/schedule';
@Injectable()
export class TasksService {
private readonly logger = new Logger(TasksService.name);
@Cron('0 0 * * *', { name: 'midnight-cleanup' })
cleanup() {
this.logger.log('Running nightly cleanup');
}
@Interval(60_000)
poll() {
this.logger.debug('Polling upstream');
}
@Timeout(5_000)
warmup() {
this.logger.log('Warming caches');
}
} The cron expression follows standard 5-field syntax (min hour dom month dow). Use named expressions like CronExpression.EVERY_HOUR to avoid
typos.
Dynamic Schedules
For schedules that depend on runtime data (per-tenant, per-user), inject
SchedulerRegistry:
import { Injectable } from '@nestjs/common';
import { SchedulerRegistry } from '@nestjs/schedule';
import { CronJob } from 'cron';
@Injectable()
export class DynamicJobs {
constructor(private registry: SchedulerRegistry) {}
add(name: string, cron: string, work: () => void) {
const job = new CronJob(cron, work);
this.registry.addCronJob(name, job);
job.start();
}
stop(name: string) {
this.registry.deleteCronJob(name);
}
} When To Pick Queues Instead
Schedules are great for in-process work that finishes quickly. If the work is heavy, retryable, or distributed across nodes, schedule the trigger but do the actual work via a BullMQ queue.
Unit Testing With Jest →