Cron schedules
Several features run on a cron schedule: SSL monitor probes, vault expiry digests, scheduled push deploys, and ACME auto-renew. This page explains the model.
The global ticker
Vercel Cron pings /api/monitor/cron once per hour. That endpoint does no per-tenant work on its own — it reads every tenant's schedule + last-run timestamp, and decides (via cron-parser) whether a firing is due in the window (last_run, now]. If yes, it runs; if no, it skips.
This means you don't need sub-hour granularity: the tightest cadence is hourly, and the ticker acts as the shared clock. You set your own cron expression; it fires within at most one hour of the target time.
Preset expressions
The UI hides the cron syntax behind presets. Here's what each one means:
0 2 * * *— Daily at 02:00 (default for monitoring)0 9 * * *— Daily at 09:00 (default for expiry digest)0 14 * * *— Daily at 14:000 */12 * * *— Every 12 hours0 */6 * * *— Every 6 hours0 * * * *— Every hour on the hour0 2 * * 1— Weekly, Monday at 02:00
Timezones
Every expression is interpreted in your account-wide timezone (Settings → Preferences). DST shifts are handled by cron-parser: your "Daily at 09:00" still fires at 09:00 local on both sides of the spring-forward / fall-back boundary, not at the naive UTC offset.
The default timezone is UTC; we try to detect your browser zone on first visit and prefill it, but you have to hit Save to commit.
What happens on a missed tick
If Vercel misses an hourly tick (rare), the next tick catches up automatically — isFireDue() checks the full window since the last run. If you're supposed to fire at 02:00 and Vercel misses that hour, you fire at 03:00 instead. You might get a slightly delayed digest but you won't miss one outright.
Seeing your last run
Each schedule records its last-run timestamp:
- Monitor probe: last_probe_run_at (visible at /dashboard/monitor)
- Expiry digest: last_expiry_digest_at (visible in Settings → Alerts)
- Scheduled push: last_scheduled_push_at (visible per-target on the Schedule panel)
- ACME renewal: renew_notified_at on the order (visible in the audit log)
Vercel Hobby limits
The function cap is 60 seconds. Current tuning:
- Up to 8 concurrent workers for monitor probes → ~480 hosts per tick
- Up to 1 ACME renewal per tick (DNS + ACME validation + finalize takes 15-40s)
- Push deploys are also 60s-capped each; we process them serially per tick
At steady state, a tenant would need thousands of hosts or dozens of simultaneous renewals to feel these limits. If you bump into them, get in touch — we have sharding options up our sleeve.