Vercel Cron Jobs
Vercel cron jobs are defined in vercel.json, always run in UTC, and call a path on your production deployment. Build a valid schedule below, then check the plan limits and the day-field rule.
The short answer
Vercel cron jobs are listed in vercel.json. Vercel sends an HTTP GET request to the path you give, on your production deployment, at the times the five-field expression describes. The time zone is always UTC.
{
"crons": [
{ "path": "/api/cron", "schedule": "0 5 * * *" }
]
}This calls /api/cron every day at 05:00 UTC. On the Hobby plan the job can start anywhere in the 05:00 hour.
Build a Vercel cron schedule
Set the fields and the output follows Vercel rules, with the next runs in your time zone. Copy the result or open it in the full Generator.
Vercel cron syntax
Vercel accepts standard five-field expressions with a narrower rule set than Linux:
| Field | Range | Example | Meaning |
|---|---|---|---|
| Minute | 0-59 | 5 * * * * | at 5 minutes past the hour |
| Hour | 0-23 | * 5 * * * | every minute between 05:00 and 05:59 |
| Day of month | 1-31 | * * 5 * * | every minute on day 5 |
| Month | 1-12 | * * * 5 * | every minute in May |
| Day of week | 0-6 (Sunday is 0) | * * * * 5 | every minute on Friday |
- No names.
MON,SUN,JANandDECare rejected. Use numbers. - One day field at a time. You cannot restrict day of month and day of week together. When one has a value, the other must be
*. - UTC only. To run at 9:00 AM New York time, convert it with the cron timezone converter.
Vercel cron examples
Each expression below passes CronWave's Vercel rules. Load one into the builder to change it.
| Expression | What it does | Use |
|---|---|---|
0 5 * * * | Runs at 5:00 AM every day. Daily. The only kind Hobby allows. | Load |
0 9 * * 1 | Runs at 9:00 AM every Monday. Every Monday. | Load |
0 0 1 * * | Runs at 12:00 AM on day 1 of every month. | Load |
*/5 * * * * | Runs every 5 minutes. Needs a plan that allows sub-daily schedules. | Load |
0 * * * * | Runs every hour, on the hour. Hourly: not for Hobby. | Load |
Plan limits and timing
| Plan | Cron jobs per project | Minimum interval | Timing precision |
|---|---|---|---|
| Hobby | 100 | Once per day | Within the hour (up to 59 minutes late) |
| Pro | 100 | Once per minute | Within the minute |
| Enterprise | 100 | Once per minute | Within the minute |
On Hobby, an expression that would run more than once a day fails the deployment, and a job set for 01:00 can start at any point up to 01:59. If you need precise or frequent runs, the Pro plan is the route Vercel documents.
How the request is sent, and how to secure it
Vercel makes an HTTP GET request to the path on your production deployment. The request carries the user agent vercel-cron/1.0 and an x-vercel-cron-schedule header with the expression that fired, which is useful when several schedules call the same path.
To stop anyone else calling the endpoint, add an environment variable named CRON_SECRET (at least 16 random characters). Vercel then sends it as an Authorization: Bearer header, and your handler compares it.
export function GET(request) {
const auth = request.headers.get('authorization');
if (!process.env.CRON_SECRET || auth !== `Bearer ${process.env.CRON_SECRET}`) {
return new Response('Unauthorized', { status: 401 });
}
// do the work
return Response.json({ ok: true });
}Reliability: retries, duplicates and redirects
- No retries. Vercel does not retry a failed invocation. Check the logs for errors.
- Best-effort delivery. A run can occasionally be missed or delivered twice, so make the job idempotent.
- Redirects are final. Cron jobs do not follow redirects; a 3xx response ends the invocation.
- Overlap. If a job runs longer than its interval, a second instance can start. Use a lock, shorten the job, or lengthen the interval.
- A missing path. A path that does not exist returns a 404, but Vercel still runs the cron job.
Common Vercel cron mistakes
- Using an hourly schedule on Hobby and wondering why the deployment fails.
- Writing
0 9 * * MON. Use0 9 * * 1. - Setting both a day of month and a day of week, for example "the 1st if it is a Monday". Vercel rejects it, and plain cron cannot express it either.
- Expecting local time. Everything is UTC.
- Checking only the schedule when the job does nothing. The expression can be right while the route is protected or redirecting. Test the path directly.
Sources and further reading
Use a tool
Try the schedule from this page in a tool.