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
| Hobby | Pro | |
|---|---|---|
| Cron jobs per project | 2 | 40 |
| Max frequency | Once per day | Per-minute schedules |
| Timing precision | Within the scheduled hour | Minute-accurate |
| Timezone | UTC only | UTC only |
| Retries on failure | None | None |
| Failure alerts | None | None |
| Invocation type | GET, subject to function maxDuration | GET, 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 * * * *or0 */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.