Monitor cron jobs in NestJS
Integrate WatchCat with NestJS scheduled tasks to get alerted when a job misses a run or throws an unhandled error.
NestJS uses the @nestjs/schedule package to run methods on a cron schedule.
Like most schedulers, it runs silently — exceptions are swallowed by default and
there's no alerting when a task stops running. A WatchCat ping at the end
of each task gives you that coverage.
Step 1 — create a cron monitor
In WatchCat, go to Cron monitors → New monitor. Set the schedule to match your task's frequency and add a grace period of a few minutes. Copy the ping URL.
Step 2 — install and register the schedule module
If you haven't already, install the package:
npm install @nestjs/schedule
Then import ScheduleModule in your root module:
import { ScheduleModule } from '@nestjs/schedule'; @Module({ imports: [ScheduleModule.forRoot()], }) export class AppModule {}
Step 3 — ping after the task runs
Add a @Cron() decorator to a service method and call the ping URL at
the end. Node 18+ has fetch built in, so no extra HTTP library is needed.
Using native fetch (Node 18+)
import { Injectable } from '@nestjs/common'; import { Cron } from '@nestjs/schedule'; const PING_URL = 'https://watchcat.io/p/cron/YOUR_TOKEN'; @Injectable() export class ReportService { @Cron('0 0 3 * * *') async generateDailyReport() { // ... your task logic ... await fetch(PING_URL); } }
Using Axios (NestJS HttpModule)
import { Injectable } from '@nestjs/common'; import { HttpService } from '@nestjs/axios'; import { Cron } from '@nestjs/schedule'; import { firstValueFrom } from 'rxjs'; const PING_URL = 'https://watchcat.io/p/cron/YOUR_TOKEN'; @Injectable() export class ReportService { constructor(private readonly http: HttpService) {} @Cron('0 0 3 * * *') async generateDailyReport() { // ... your task logic ... await firstValueFrom(this.http.get(PING_URL)); } }
Start and end tracking
For tasks that run for more than a few seconds, use start and end pings wrapped in a try/catch so WatchCat can detect tasks that started but never finished.
const PING = 'https://watchcat.io/p/cron/YOUR_TOKEN'; @Cron('0 */30 * * * *') async syncOrders() { await fetch(`${PING}/start`); try { // ... your task logic ... await fetch(`${PING}/end`); } catch (err) { await fetch(`${PING}/fail`); throw err; } }
Using CronExpression constants
@nestjs/schedule exports a CronExpression enum with
named presets as an alternative to writing cron strings by hand:
import { Cron, CronExpression } from '@nestjs/schedule'; @Cron(CronExpression.EVERY_DAY_AT_3AM) async runNightlyJob() { ... } @Cron(CronExpression.EVERY_30_MINUTES) async pollExternalApi() { ... }
NestJS uses a six-field cron expression (with a leading seconds field), matching
Spring's format. In WatchCat, set the expected interval to match your task's
run frequency — for example, a task that runs every 30 minutes uses an interval of
30 minutes; a task using EVERY_DAY_AT_3AM uses an interval of 1 day.
Recommended settings
@Cron() frequency
Start monitoring in minutes
Free plan available. No credit card required.