Skip to content
Knowledge base

Monitor Vercel cron jobs with a heartbeat

Vercel calls your cron route on schedule but does not retry a failed invocation or tell you about one. Ping a heartbeat from the route itself and a skipped or failed run becomes an alert.

1. Know what Vercel does and does not promise

A cron job in vercel.json is a schedule plus a path, and Vercel requests that path on schedule. Its documentation says it will not retry an invocation if a cron job fails. On the Hobby plan, cron jobs may run at most once a day, and a job set for 1 am can fire anywhere between 1:00 and 1:59. Pro runs to the minute.

2. Create the heartbeat

Add a monitor with Check type Heartbeat (cron), set the interval to the schedule's period (86400 seconds for a daily job), and give it grace for the run time plus, on Hobby, the extra hour of timing slack. Copy the ping URL when it is shown and add it to the project's environment variables as REALUPTIME_PING_URL.

3. Ping at the end of the route, after the work succeeds

In the route handler, do the work first, then: await fetch(process.env.REALUPTIME_PING_URL). In a catch block, call the same URL with /fail appended so the monitor goes down at once with run-failed wording. Keep Vercel's recommended CRON_SECRET check at the top of the route so only Vercel's scheduler can trigger it.

4. What the heartbeat catches

A deploy that drops the cron entry, a route that starts returning errors, a function that times out before reaching the ping, and a run that never fires all end the same way: no success ping before interval plus grace, so the monitor goes down and alerts through your usual channels. Heartbeats are on every plan, Free included.

Go deeper

The full reference lives in the docs: Heartbeat monitors documentation. Error codes named above are each explained in the error-code reference.