Symptoms / Fix guide

Why is my Vercel cron job not running?

Matt Turley, Continuum. Updated November 5, 2026.

For founders whose nightly email, sync, cleanup or billing job works when called by hand and never runs on schedule.

The short answer

Why is my Vercel cron job not running?

Vercel runs cron jobs only against the production deployment, by sending a GET request to a path you list in vercel.json. If the job does nothing, the path is wrong, the route rejects the request (often a secret header or middleware), the function times out, or your plan limits how often it can run. The cron log shows which.

What is really going on

A cron job on Vercel is not a process that runs on a clock. It is an HTTP request that Vercel sends to a route in your production deployment on a schedule. So everything that can go wrong with a normal request can go wrong with a cron job: the route can 404, redirect, be blocked by middleware, throw or time out. The difference is that nobody is watching the request.

The jobs AI tools write often assume a long-lived server, a writable disk or an unlimited run time. A serverless function is limited on time, so a job that processes a large backlog in one call can start, run out of time and leave the work half done.

The fix is the same as for any silent failure: make the job observable. A job that cannot tell you it ran, and what it did, will fail unnoticed.

The usual causes, most common first

  1. The job is not in the production deployment

    How to tell Nothing happens on schedule but calling the URL by hand works on a preview. Cron jobs run against production only and are created from the crons entry in vercel.json when a production deployment goes live.

    The fix Confirm the configuration is in the branch that deploys to production, that the deployment finished, and check the Cron Jobs list in the project to see the registered paths.

  2. The path is wrong or the route is the wrong method

    How to tell The cron log shows a 404 or 405. The configured path does not match the route file, or the route handles only POST. Vercel invokes cron paths with GET.

    The fix Make the path in vercel.json match the route exactly, and export a GET handler for it.

  3. The route rejects the request

    How to tell The log shows 401 or 403. If you set a CRON_SECRET variable, Vercel sends it as an authorization header, and your route must compare it. A route behind auth middleware, or one that expects a user session, returns 401 to Vercel.

    The fix Check the Authorization: Bearer header against CRON_SECRET inside the route, and exclude the cron path from user-session middleware. Do not leave the route open to anyone who guesses the URL.

  4. The function times out or errors partway

    How to tell The log shows a timeout or 500, and the job does some of its work. A job that loops over every user in one call hits the function duration limit as data grows.

    The fix Process in small batches, store progress, and let the next run continue. Move long work to a queue or background function.

  5. The schedule is not what you think

    How to tell The job runs, but at the wrong time. Cron expressions are interpreted in UTC, and plans differ in how often and how precisely a job may run. A schedule that is more frequent than your plan allows can be rejected at deploy.

    The fix Write the schedule in UTC, check your plan's current cron limits in the documentation and look at the deployment output for a rejected schedule.

  6. It runs twice, or overlaps itself

    How to tell Duplicate emails or double charges. A scheduled invocation can occasionally arrive more than once, and a slow run can overlap the next.

    The fix Make the job idempotent and take a lock or mark records as processed before acting on them.

How we diagnose it

  1. Read the cron log for the job. The project's cron jobs view and the function logs show each invocation, its status code and its duration. That one screen separates "never invoked" from "invoked and failed".
  2. Compare configuration with the route. We read vercel.json, the route file path and the exported methods side by side, and confirm the production deployment contains both.
  3. Call it as Vercel would. Send a GET request to the production path with the authorization header and read the response, without involving the schedule.
  4. Measure the run. Time a full run against production data. If it is near the function limit now, it will fail as data grows.
  5. Add proof that it ran. Write a row or a log line each time the job starts and finishes, and alert when one is missing. A fix is confirmed by a scheduled run, not a manual one.

What fixing it changes

  • The cron configuration, the route path and the HTTP method agree, in the production deployment.
  • The route checks the secret header and is excluded from user-session middleware.
  • Work is done in batches with saved progress, so a timeout cannot lose it.
  • The job is safe to run twice and records every run.
  • An alert fires when an expected run does not happen.

When you do not need us

A wrong path, a missing GET handler or a header check are quick fixes you can make with the cron log open. You need a person when the job is part of a chain (billing, syncing, sending) and a missed or doubled run costs money.

Your next step

Background jobs are where an AI-built app fails without telling anyone. A Ship Check reads the whole codebase, including scheduled work, and ranks what will break first.

Ship Check, $299: A senior engineer reads your codebase and sends a written verdict (fine, fixable or rewrite), what will break first, a security and data read, and a costed plan, within 48 hours of repo access or it is free. It has a 7-day money-back and is credited against a Ship Fix. Or: Book a call.

Get a Ship Check, $299 →See all services and prices →
FAQ

Straight answers

Can I test a Vercel cron job locally?
Not on a schedule. Vercel does not run the schedule on your machine. Call the route yourself with the same method and header, and keep the route's logic in a function you can test directly.
Why does my cron job run on production but not on a preview?
Cron jobs are created for production deployments only. A preview deployment will not run scheduled invocations, although you can call its route by hand to test the logic.
Do I need a separate queue service?
Not at first. Small batches with saved progress go a long way. Reach for a queue when a single run cannot finish in the time a function is allowed, or when you need retries with backoff for each item.
Keep reading
Why does my app work locally but break in production?By symptom. Production differs from your laptop in environment variables, database, file system, Node version and network rules. The usual causes and how to check each.A customer paid, but the order is not in my CRM. Why?By symptom. Payment and CRM record are two separate writes joined by your code. Where the chain usually breaks, how to trace one order end to end, and how to fix it.My app broke right after launch. What do I do first?By stage. The first hours after a launch goes wrong: stop the damage, find the failure, protect users and data, then make it stable. What usually breaks, in order.What breaks in an AI-built B2B SaaS app before launch?By vertical. For B2B SaaS built with AI tools: tenant isolation, roles, invites, billing and the enterprise asks that arrive first. What breaks and how to check.What breaks in an AI wrapper app before it scales?By vertical. Apps built on top of an LLM API: exposed provider keys, unbounded spend, no per-user limits, prompt injection, user data in prompts and serverless timeouts.Why is my Stripe webhook not firing?By symptom. Stripe is usually sending the event and your server is refusing it. How to read the delivery log, the six usual causes, and the fix for each.
Sources
  1. 1. Vercel: Cron Jobs, Vercel: How cron jobs are configured and invoked, and that they run on production deployments.
  2. 2. Vercel: Managing Cron Jobs, Vercel: Securing cron routes with CRON_SECRET, duration limits and handling duplicate invocations.
  3. 3. Vercel: Cron Jobs usage and pricing, Vercel: The plan limits on how many jobs and how often they can run.
Why is my Vercel cron job not running? | Continuum