Troubleshooting · Vercel

Vercel cron limits explained: Hobby vs Pro

Every Vercel cron job limit in one place — 2 jobs and once-per-day on Hobby, the within-the-hour timing window, UTC-only schedules, function duration caps — and what to do when you outgrow them.

Vercel cron jobs come with plan limits that are easy to miss until they bite. Here they all are in one place — with the workarounds.

The limits at a glance

HobbyPro
Cron jobs per project240
Max frequencyOnce per dayPer-minute schedules
Timing precisionWithin the scheduled hourMinute-accurate
TimezoneUTC onlyUTC only
Retries on failureNoneNone
Failure alertsNoneNone
Invocation typeGET, subject to function maxDurationGET, subject to function maxDuration

Three of these surprise almost everyone:

1. “Once per day, sometime that hour” (Hobby)

On Hobby, 0 3 * * * doesn’t mean 03:00 — it means somewhere between 03:00 and 03:59 UTC. That’s a deliberate load-spreading measure. Consequences:

  • consecutive runs can be ~23 to ~25 hours apart — don’t build “exactly 24h” assumptions into the job;
  • a “midnight cleanup” can fire at 00:47 and overlap with early-morning traffic;
  • you cannot schedule anything intraday: */10 * * * * or 0 */6 * * * are invalid on Hobby and won’t run as written.

2. UTC-only, on every plan

There is no timezone setting. If the business requirement is “09:00 in Berlin”, your cron fires at 07:00 UTC in summer and 08:00 UTC in winter — someone has to edit vercel.json twice a year, and redeploy, to keep it honest.

3. No retries, no alerts — the limit nobody lists

The quiet one: a cron invocation that 500s or times out is simply over. No retry, no email, no dashboard warning. On any plan. The Vercel cron troubleshooting guide covers the failure modes in detail.

When you hit the limits

Upgrade to Pro solves frequency and precision — but not timezones, retries, or alerting.

Or split the trigger from the compute. Your route stays exactly where it is; an external scheduler calls it:

jobs:
  - id: cleanup
    name: Cleanup
    kind: http
    method: GET
    url: https://your-app.vercel.app/api/cleanup
    schedule: "*/10 * * * *"        # any frequency, any plan
    timezone: Europe/Berlin          # real timezones, DST-aware
    retries: 3                       # retries with backoff
    headers:
      Authorization: Bearer ${CRON_SECRET}

That gives you intraday schedules on a Hobby project, minute-accurate timing, per-job timezones, retries, and failure alerts (email, Slack, Discord, Telegram) — while the function itself keeps running on Vercel. steadycron import vercel converts your existing vercel.json in one command: see migrating from Vercel cron.

Frequently asked questions

How many cron jobs does the Vercel Hobby plan allow?

Two cron jobs, each running at most once per day. Schedules more frequent than daily are invalid on Hobby and will not run as written.

How exact is Vercel cron timing on the Hobby plan?

Deliberately inexact: the run lands anytime within the scheduled hour. 0 3 * * * means "between 03:00 and 03:59 UTC". Minute-level precision requires the Pro plan.

Can Vercel cron jobs run in my local timezone?

No — schedules are UTC-only on every plan, with standard 5-field cron syntax and no seconds field. A "9 AM Berlin" job shifts an hour at every daylight-saving change.

Does Vercel retry failed cron jobs?

No, on any plan. A failed invocation is logged and gone — there are no retries and no failure alerts. If a run matters, add a heartbeat monitor or trigger the route from a scheduler that retries.