Bypassing the Vercel Hobby Plan Cron Limit

A note from the founder. Need to schedule your Vercel routes more frequently than once a day? I'm looking for a small group of early users to try Runhooks and share honest feedback. Early adopters get upgraded plans for free.

You build a Next.js app on Vercel, add an API route that syncs data from an external service, and open vercel.json to schedule it every hour. Then you hit the wall: Vercel's Hobby plan only allows cron jobs that run once per day.

Your code is ready. Your API route works. The only thing stopping you is a platform restriction on scheduling frequency.

The Vercel Hobby Plan Cron Limitation

Vercel supports cron jobs through a crons configuration in vercel.json. You define which API route to invoke and on what schedule:

{
  "crons": [
    {
      "path": "/api/sync",
      "schedule": "0 * * * *"
    }
  ]
}

On the Pro plan ($20/month per team member), this works as expected — you can schedule routes at any frequency. On the Hobby plan (free), Vercel enforces a hard limit: cron expressions can only resolve to once per day or less. Setting 0 * * * * (every hour) or */15 * * * * (every 15 minutes) will fail during deployment.

This means if you need a Next.js cron job running hourly — to sync data, send digests, refresh caches, or poll an external API — you're forced to either upgrade to Pro or find an alternative.

Why the Limit Exists

Vercel's cron feature invokes your API routes as serverless functions. Each invocation consumes compute resources. Restricting Hobby accounts to daily execution keeps free-tier infrastructure costs predictable.

The limitation is in Vercel's scheduler configuration, not in your API routes themselves. Your /api/sync route is a standard HTTP endpoint — it responds to any GET or POST request regardless of who sends it. Vercel's cron is just one way to trigger it.

The Workaround: An External Scheduler

Since your API routes are regular HTTP endpoints, any service that can send an HTTP request on a schedule can replace Vercel's built-in cron. You don't need to change your Next.js code — you just need something outside Vercel to call your routes.

The approach:

  1. Keep your API route as-is — no code changes needed
  2. Remove the crons config from vercel.json (or leave it for a daily fallback)
  3. Use an external scheduler to GET or POST your route on whatever frequency you need

This works because Vercel doesn't restrict incoming requests to your API routes — only the built-in cron scheduler is limited.

What You Lose With a DIY Approach

You could point a cron job on your own machine at your Vercel API route. But this trades one problem for several:

  • No reliability. Your laptop sleeps, your VPS reboots, and the scheduled job stops — silently.
  • No visibility. There's no log of which invocations succeeded, failed, or timed out.
  • No retries. Serverless cold starts or transient errors mean a missed run. Cron won't retry — the next attempt is on the next scheduled tick.
  • No alerts. If your API route starts returning 500 errors, you won't know until you manually check.

For a scheduled task that matters — data syncs, notifications, cache refreshes — silent failures aren't acceptable.

How Runhooks Replaces Vercel Cron

Runhooks is a scheduled HTTP execution service that calls your endpoints on a schedule with built-in reliability. It works as an external orchestration layer for serverless platforms like Vercel.

Setup for a Next.js API route:

  1. Create a job — name it "Hourly data sync"
  2. Set the URLhttps://your-app.vercel.app/api/sync
  3. Set the schedule0 * * * * (every hour), */15 * * * * (every 15 minutes), or any valid cron expression
  4. Set the methodGET or POST, with optional headers and body
  5. Enable retries — 3 attempts with exponential backoff

No vercel.json cron config needed. No Vercel plan upgrade. Your Next.js code stays exactly the same.

What you get that Vercel's built-in cron doesn't provide — even on Pro:

  • Execution logs — every invocation is recorded with HTTP status, response body, and duration in milliseconds
  • Automatic retries — if a cold start causes a timeout, the next attempt fires within seconds instead of waiting for the next scheduled tick
  • Failure alerts — email or webhook notifications when your route is consistently failing
  • Flexible scheduling — any cron expression, with timezone support and a visual schedule preview

Securing Your API Route

When your API route is triggered externally instead of by Vercel's internal cron, you should verify that incoming requests are legitimate. A simple approach is a shared secret in a header:

// app/api/sync/route.ts (Next.js App Router)
export async function GET(request: Request) {
  const authHeader = request.headers.get('authorization');
  if (authHeader !== `Bearer ${process.env.CRON_SECRET}`) {
    return Response.json({ error: 'Unauthorized' }, { status: 401 });
  }

  // your sync logic here
  return Response.json({ status: 'ok' });
}

In Runhooks, add an Authorization: Bearer <your-secret> header to the job configuration. This ensures only your scheduled jobs can invoke the route.

Get Started

Vercel's Hobby plan is great for deploying Next.js apps — the daily cron limit is the main constraint for automation, and it's easy to work around:

  1. Keep your API routes as standard HTTP endpoints
  2. Try Runhooks and schedule them at any frequency
  3. Get retries, logs, and alerts that Vercel cron doesn't include

Test your cron expressions with the cron expression visualizer, and compare plans when you need more jobs or longer log retention.

Read next: Eliminating Render Free Tier Cold Starts · Scheduled HTTP Requests vs. Cron Jobs · Why Cron Jobs Fail in Production