Platform schedule guide

Vercel Cron Jobs Guide

Configure Vercel Cron Jobs safely with five-field expressions, UTC timing, vercel.json examples, plan accuracy, CRON_SECRET authentication, idempotency, and concurrency guidance.

Platform behavior reviewed against the official documentation on August 5, 2026.

Format
5 numeric fields
Timezone
Always UTC
HTTP method
GET
Failure retry
No automatic retry

Overview

Vercel Cron Jobs turn a schedule into an HTTP GET request to a path on the production deployment. They are a convenient fit for Next.js route handlers and other Vercel Functions because the schedule lives beside the application in vercel.json.

Vercel accepts a restricted five-field cron format and always evaluates it in UTC. Unlike general Unix cron, aliases such as MON, SUN, JAN, and DEC are not supported, and day-of-month and day-of-week cannot both be constrained.

A successful HTTP trigger is only the start of the job. Vercel does not retry a failed cron invocation, overlapping runs are possible, and duplicate delivery can occur, so the endpoint needs authentication, idempotency, locking, and observable completion.

Vercel cron expression format

The fields are minute, hour, day-of-month, month, and day-of-week. Use numeric values only. A schedule is attached to an application path, which Vercel requests on the production deployment.

When day-of-month is specific, day-of-week must be *. When day-of-week is specific, day-of-month must be *. This is stricter than classic Unix cron and prevents ambiguous combined-day behavior.

┌───────────── minute (0-59)
│ ┌───────────── hour (0-23)
│ │ ┌───────────── day of month (1-31)
│ │ │ ┌───────────── month (1-12)
│ │ │ │ ┌───────────── day of week (0-6, Sunday=0)
│ │ │ │ │
* * * * *
Vercel Cron Jobs schedule fields and valid values
FieldPositionValuesPlatform note
Minute10-59Paid-plan invocations arrive within the selected minute.
Hour20-23Always UTC; convert local wall-clock requirements.
Day of month31-31Day of week must be * when this is constrained.
Month41-12Text aliases such as JAN are not accepted.
Day of week50-6Sunday is 0; text aliases such as MON are not accepted.

Copyable schedule examples

Every day at 02:00 UTC

0 2 * * *

Every 15 minutes on plans that allow that frequency

*/15 * * * *

Weekdays at 09:00 UTC

0 9 * * 1-5

First day of every month at 04:30 UTC

30 4 1 * *

Configure vercel.json and a Next.js route

The schedule points at an existing production path. Vercel sends CRON_SECRET as a Bearer token when that environment variable is configured, so reject requests that do not carry the expected Authorization header.

// vercel.json
{
  "$schema": "https://openapi.vercel.sh/vercel.json",
  "crons": [
    { "path": "/api/cron/nightly", "schedule": "17 2 * * *" }
  ]
}

// app/api/cron/nightly/route.ts
export async function GET(request: Request) {
  const secret = process.env.CRON_SECRET;
  if (!secret || request.headers.get('authorization') !== `Bearer ${secret}`) {
    return new Response('Unauthorized', { status: 401 });
  }

  await runIdempotentNightlyJob();
  return Response.json({ ok: true });
}

Deployment checklist

  1. Create the route and call it directly in development with the same authorization contract.
  2. Add CRON_SECRET as a production environment variable with a random value of at least 16 characters.
  3. Add the crons entry to vercel.json and deploy; configuration changes take effect through a deployment.
  4. Verify the Cron Jobs settings page and runtime logs, then alert on a missing application-level success signal.

UTC-only scheduling

Vercel Cron Jobs always evaluate expressions in UTC and do not provide a per-job timezone property. For a fixed UTC instant, convert the desired time once and document the conversion.

A single UTC expression cannot keep a job at the same local wall-clock hour across daylight-saving changes. For that requirement, either update the expression seasonally, run at candidate UTC times and gate inside the application using an IANA timezone, or use a scheduler with native timezone support.

Turkey currently uses UTC+3 year-round, so 09:00 Europe/Istanbul maps to 06:00 UTC. For zones with DST, never assume the current offset applies throughout the year.

// 09:00 Europe/Istanbul (UTC+3) -> 06:00 UTC
{ "path": "/api/cron/report", "schedule": "0 6 * * *" }

Limits and platform behavior

Plan-dependent frequency and accuracy
Hobby cron jobs can run only once per day and may be invoked at any point within the selected hour. Other teams are invoked within the selected minute.
Numeric fields only
Use 1-5 instead of MON-FRI and 1 instead of JAN. Alternative names are rejected.
No combined day constraints
Only one of day-of-month and day-of-week may be constrained; the other must be *.
Function duration
Cron invocations use the same duration limits as the underlying Vercel Function runtime.

Production gotchas

  • No failure retry

    Vercel does not retry a failed cron invocation. Put retryable work on a durable queue or add a reconciliation process.

  • Overlapping and duplicate invocations

    A long job can overlap its next run, and the same event can occasionally be delivered more than once. Use both a distributed lock and idempotent writes.

  • Redirects are final

    Cron requests do not follow redirects. Point the schedule directly at the final route and return a useful non-redirect response.

  • Cached responses hide work

    Ensure the handler performs dynamic work rather than returning a cached response, and verify completion in application telemetry.

Frequently asked questions

What timezone do Vercel Cron Jobs use?

Vercel Cron Jobs always use UTC. There is no timezone field in a Vercel cron definition.

Does Vercel retry a failed cron job?

No. Vercel does not automatically retry failed cron invocations, so durable work should use its own retry or queue mechanism.

Can a Vercel cron job run twice?

Yes. Duplicate delivery can occasionally occur, and a long invocation may overlap the next one. Use idempotency and a lock.

Can Vercel cron use MON or JAN?

No. Vercel requires numeric values for weekdays and months and does not support aliases such as MON, SUN, JAN, or DEC.

Official documentation and related guides