How to monitor Node.js scheduled jobs
To monitor a Node.js scheduled job, ping a monitoring URL when the job starts and when it finishes, and send /fail with the error if it throws. Cronomonitor alerts you on a failure, a hang, or a run that never happens.
Why monitor it
Whether the job runs from cron, node-cron, a BullMQ repeatable job or a serverless scheduler, an unhandled rejection or a process that exits early is easy to miss. The pings make each run visible.
1. Create a check
Sign up for Cronomonitor, create a project and add a check named after the job. Give it the job's schedule, here the cron expression 0 3 * * * (every day at 3am, UTC), and a grace period that covers how long the job normally takes.
The check gives you a unique ping URL. Every snippet below is also on the check's page in the dashboard, already filled in with that URL and schedule.
2. Add the ping to your job
Needs Node.js 18 or later, in an ES module (for top-level await).
const PING_URL = "https://cronomonitor.com/api/ping/<your-check-id>";
// Never let monitoring break the job.
const ping = (path = "", body) =>
fetch(PING_URL + path, { method: "POST", body, signal: AbortSignal.timeout(10_000) }).catch(() => {});
await ping("/start");
try {
await runJob(); // your code here
await ping();
} catch (error) {
await ping("/fail", String(error?.stack ?? error).slice(-10_000));
throw error;
}How it works
The ping helper uses Node's built-in fetch with a 10-second timeout and ignores network errors, so monitoring can never break the job. If the job throws, the end of the stack trace goes with the /fail ping, then the error is re-thrown as before.
Put your job's code where runJob() is called.
Inside a long-running process
With node-cron or a BullMQ repeatable job, wrap the handler in the same pings. If the whole process dies, the pings stop and Cronomonitor alerts you, which an in-process error handler can't do.
Serverless schedulers
In a scheduled serverless function, await the final ping before returning: some platforms freeze the function as soon as the handler returns, and an un-awaited request may never be sent.
3. Test it
Run the job once by hand, or use Send a test ping on the check. The check turns green as soon as the first ping arrives, and from then on Cronomonitor expects the next one on schedule.
To check where alerts go, use Send test alert on the check. To see a real failure alert, make the job exit with an error once.
If the check says the job didn't run
Run the script by hand with the same Node.js version the scheduler uses.
Read the check's ping log: a /start ping with no finish means the job hung or the process was killed.