Migrating production infrastructure? Get up to ₹10,000 in migration credits. Apply now
voroaBlog
Background Workers

Vercel Cron Jobs: Limits, Setup and the Traps in 2026

· · 6 min read

Vercel cron jobs, the limits, the setup and the traps, checked against Vercel's documentation

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

Advertisement

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

json
// vercel.json
{
  "crons": [
    { "path": "/api/digest", "schedule": "30 3 * * *" }
  ]
}
js
// 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.

Diagram: a job scheduled for 8:00 UTC on Vercel Hobby can start anywhere between 8:00 and 8:59, while on Pro it starts within 8:00 to 8:00:59; 8:00 UTC is 1:30 pm in India

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:

  1. Add an environment variable CRON_SECRET, a random string of at least 16 characters.
  2. Vercel sends it in the Authorization header as Bearer <secret> on every cron call.
  3. 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.

Advertisement