← Back to Docs

Run a Vercel Cron Job More Than Once a Day (Hobby Plan)

On Vercel's Hobby plan a cron job can run at most once a day, and a schedule like */15 * * * * fails the deploy with "Hobby accounts are limited to daily cron jobs." Vercel's docs also say Hobby timing is not precise. The usual fix is to keep your cron logic in a normal API route and have an outside scheduler call that route over HTTP. Here is how to do that with RunLater.

1. Protect the route with a secret

Your route is a public URL, so check a bearer token before doing any work:

// app/api/cron/sync/route.ts
export async function GET(req: Request) {
  if (req.headers.get('authorization') !== `Bearer ${process.env.CRON_SECRET}`) {
    return new Response('Unauthorized', { status: 401 });
  }
  // ... your job
  return Response.json({ ok: true });
}

Add CRON_SECRET to your Vercel project's environment variables and redeploy.

2. Remove the schedule from vercel.json

Delete the crons entry for this route so the deploy no longer fails.

3. Create the scheduled request in RunLater

  1. URL: https://your-app.vercel.app/api/cron/sync
  2. Method: GET (or POST if your route expects it)
  3. Header: Authorization: Bearer <your CRON_SECRET>
  4. Schedule: any cron expression, down to once a minute, for example */15 * * * *
  5. Timezone: pick yours, so "9am" means your 9am
  6. Retries: 3 is a good start; a cold start or a 5xx gets retried with backoff

Not sure about the expression? Paste it into the cron expression explainer to see the next run times.

What you get

  • Per-minute schedules without upgrading your Vercel plan
  • A log of every run with the status code, timing and response body
  • Schedule changes without a redeploy

Each call still runs as a Vercel function, so it counts toward your Vercel usage. RunLater Starter is $15/month for 250 scheduled requests and 25,000 runs, after a 14-day trial. If one daily job is all you need, Vercel's built-in cron is free and is the simpler choice.