Vercel Cron Jobs: Limits, Setup and the Traps in 2026
Sagar Tayde · · 6 min read
Vercel cron jobs call one of your functions on a schedule. You add a path and a cron expression to
vercel.json, deploy, and Vercel sends a request to that path at the times you set.
It is simple, and it has rules that surprise people: a once-a-day limit on the free plan, UTC-only times, no retries, and occasional duplicate runs. This guide covers the setup and each rule, all from Vercel’s own documentation, checked on 7 November 2026.
On this page
- How they work
- Setup in two files
- Plan limits
- Seven rules that catch people out
- Securing the endpoint with CRON_SECRET
- Schedules: the replacement
- When to run cron somewhere else
- FAQ
How they work
At each scheduled time, Vercel makes an HTTP GET request to your production deployment, at the path
you configured. The request carries the user agent vercel-cron/1.0 and an x-vercel-cron-schedule
header with the expression that triggered it.
Your function runs as a normal request. So the job is limited by your function’s maximum duration, and it only exists while that request is being handled.
Setup in two files
// vercel.json
{
"crons": [
{ "path": "/api/digest", "schedule": "30 3 * * *" }
]
}
// app/api/digest/route.js (Next.js App Router)
export async function GET(request) {
if (request.headers.get('authorization') !== `Bearer ${process.env.CRON_SECRET}`) {
return new Response('Unauthorized', { status: 401 });
}
await sendDailyDigest(); // your code
return Response.json({ ok: true });
}
30 3 * * * is 3:30 UTC, which is 9:00 am in India. Vercel schedules in UTC only.
Plan limits
| Hobby | Pro | Enterprise | |
|---|---|---|---|
| Cron jobs per project | 100 | 100 | 100 |
| Shortest interval | Once a day | Once a minute | Once a minute |
| Timing | Anywhere within the scheduled hour | Within the scheduled minute | Within the scheduled minute |
On Hobby, an expression that runs more than once a day, such as 0 * * * *, fails the deployment. And a
job set for 0 8 * * * can start any time from 08:00 to 08:59 UTC. Source:
Vercel cron usage and pricing.

Seven rules that catch people out
1. Failed runs are not retried. If the function errors, Vercel does not try again. You find out only from the logs.
2. Delivery is best effort. Vercel says a network error can occasionally stop a run from reaching your function, and then nothing runs and nothing is logged.
3. A run can arrive twice. Vercel also says the same scheduled run can occasionally be delivered more than once. Make the job safe to repeat.
4. Runs can overlap. If a run takes longer than the interval, Vercel can start the next one anyway. Vercel suggests a lock, for example in Redis, to allow only one at a time.
5. Only production runs crons. Preview deployments never trigger them. Test by calling the path yourself.
6. Redirects end the run. Cron requests do not follow redirects. With Next.js trailingSlash
turned on, /api/digest redirects to /api/digest/ and your function never runs. Put the trailing
slash in the configured path.
7. Expression limits. No names such as MON or JAN, and you cannot set both day-of-month and
day-of-week; one of them must be *.
These come from Vercel’s managing cron jobs page. Rules 3 and 4 are the same lessons we measured for in-process schedulers: our node-cron tests saw both duplicate and overlapping runs.
Securing the endpoint with CRON_SECRET
A cron path is a public URL, so anyone could call it. Vercel’s fix:
- Add an environment variable
CRON_SECRET, a random string of at least 16 characters. - Vercel sends it in the
Authorizationheader asBearer <secret>on every cron call. - Your function rejects any request without the matching header, as in the code above.
Each deployment keeps the secret it was built with. Changing CRON_SECRET does nothing until you
redeploy, and an instant rollback brings back the older deployment’s secret.
Schedules: the replacement
Vercel now describes Cron Jobs as a legacy feature that will move to Schedules, which add timezones and private function targets. Schedules were in public beta at the time of writing.
The limits change too. According to Vercel’s migration guide, Hobby schedules can run as often as once every 15 minutes, within a 15-minute window, instead of once a day.
If timezones are the reason you are reading this, check the Schedules documentation before building around UTC. Existing cron routes can move to Schedules without code changes, according to Vercel.
When to run cron somewhere else
Vercel cron is a good fit for short tasks that are safe to retry by hand: refreshing a cache, sending a digest, syncing a small list. Consider a separate cron service when:
- The job runs longer than your function’s maximum duration.
- You are on Hobby with legacy Cron Jobs and need more than one run a day.
- Your users are in India and you want schedules in IST without converting from UTC (legacy Cron Jobs are UTC-only).
For the general limits of each platform side by side, see our guide to cron every 5 minutes.
Running scheduled jobs on Voroa
On Voroa, a Cron Job runs a command from your repository on a schedule, as a process rather than an HTTP request to a function. Schedules are in India Standard Time and can run as often as every minute.
Voroa builds the repository into a small service that stays running, so a slow run can overlap the next. Runs are skipped while the service is stopped, for example after a free workspace uses its monthly free hours. Voroa does not retry a failed run either, so keep jobs idempotent and record each success.
Setup is in scheduling a task on Voroa, and you can host the Next.js app itself as a web service. Long-running consumers belong on the background workers page.
FAQ
Are Vercel cron jobs free? They are included on every plan; you pay for the function time they use. On Hobby they can run at most once a day.
What timezone do Vercel cron jobs use?
UTC, always. For 9 am in India, write 30 3 * * *.
Why is my Vercel cron job not running?
Common causes: it is a preview deployment, a redirect such as trailingSlash, a 401 from a
CRON_SECRET mismatch, or a Hobby expression that runs more than once a day.
Does Vercel retry failed cron jobs? No. A failed invocation is not retried. Check the logs from the Cron Jobs settings page.
Can a Vercel cron job run twice? Yes, occasionally. Vercel says delivery can repeat a run, and a long run can overlap the next.
How do I secure a Vercel cron job?
Set CRON_SECRET, then reject requests whose Authorization header is not Bearer plus that secret.
Checked 7 November 2026 against Vercel’s documentation. Found something out of date? Write to support@getvoroa.com.