DevToolBoxFREE
Blog

Cron Schedule for Serverless: GitHub Actions, Vercel Cron, and Cloudflare Workers

9 min readby DevToolBox
Ad Space

Cron expressions are the universal language for scheduling recurring tasks. But when you move from traditional crontab to serverless platforms, each platform has its own quirks, limitations, and syntax differences. This guide covers everything you need to schedule jobs on the three most popular serverless platforms.

Cron Expression Basics (60-Second Refresher)

A standard cron expression has 5 fields:

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ minute (0-59)
│ ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ hour (0-23)
│ │ ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ day of month (1-31)
│ │ │ ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ month (1-12)
│ │ │ │ ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ day of week (0-6, Sun=0)
│ │ │ │ │
* * * * *

Common special characters:

  • * — any value
  • */5 — every 5 units (step)
  • 1,3,5 — specific values (list)
  • 1-5 — range of values

Test your cron expressions with our Cron Parser tool →

Platform 1: GitHub Actions

GitHub Actions uses the schedule event with standard 5-field cron syntax. Scheduled workflows run on the default branch only.

Configuration

# .github/workflows/scheduled.yml
name: Scheduled Job
on:
  schedule:
    - cron: '30 5 * * 1-5'  # Weekdays at 5:30 AM UTC
    - cron: '0 12 1 * *'    # 1st of every month at noon UTC
jobs:
  run:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: echo "Running scheduled task"

Key Limitations

AspectDetails
TimezoneUTC only — no timezone configuration
Minimum intervalEvery 5 minutes (*/5 * * * *)
AccuracyCan be delayed 5-15 minutes during peak load
BranchRuns on default branch only
Disable conditionAuto-disabled after 60 days of repo inactivity

Common Schedules for GitHub Actions

# Every 5 minutes
- cron: '*/5 * * * *'

# Every hour at minute 0
- cron: '0 * * * *'

# Daily at midnight UTC
- cron: '0 0 * * *'

# Daily at 9 AM Eastern (UTC-5, no DST)
- cron: '0 14 * * *'

# Weekdays at 8 AM UTC
- cron: '0 8 * * 1-5'

# Every Monday and Thursday at 6 PM UTC
- cron: '0 18 * * 1,4'

# First day of every month at midnight
- cron: '0 0 1 * *'

Tip: GitHub Actions scheduled workflows may not fire exactly on time. If you need precision, use a webhook-based trigger from a more reliable scheduler.

Platform 2: Vercel Cron Jobs

Vercel Cron Jobs trigger serverless functions on a schedule. Configure them in vercel.json.

Configuration

// vercel.json
{
  "crons": [
    {
      "path": "/api/daily-report",
      "schedule": "0 8 * * *"
    },
    {
      "path": "/api/cleanup",
      "schedule": "0 0 * * 0"
    }
  ]
}

The API Route

// app/api/daily-report/route.ts
import { NextResponse } from 'next/server';

export async function GET() {
  // Your scheduled logic here
  await sendDailyReport();
  return NextResponse.json({ ok: true });
}

// Vercel recommends setting maxDuration for long tasks
export const maxDuration = 60; // seconds

Key Limitations

PlanMin IntervalMax Cron JobsExecution Limit
Hobby (free)Once per day210s
ProOnce per hour4060s (default)
EnterpriseOnce per minute100900s

Important: Vercel Cron Jobs use UTC timezone. The Hobby plan's once-per-day limit means expressions like */5 * * * * will not work — they'll only fire once daily.

Platform 3: Cloudflare Workers (Cron Triggers)

Cloudflare Workers Cron Triggers are configured in wrangler.toml and run at the edge globally.

Configuration

# wrangler.toml
name = "my-worker"
main = "src/index.ts"

[triggers]
crons = [
  "*/5 * * * *",    # Every 5 minutes
  "0 12 * * 1-5",   # Weekdays at noon UTC
  "0 0 1 * *"       # First of every month
]

Worker Code

// src/index.ts
export default {
  async scheduled(
    controller: ScheduledController,
    env: Env,
    ctx: ExecutionContext
  ) {
    // controller.cron contains the cron pattern that triggered
    switch (controller.cron) {
      case '*/5 * * * *':
        await doHealthCheck(env);
        break;
      case '0 12 * * 1-5':
        await sendReport(env);
        break;
    }
  },
};

Key Limitations

AspectDetails
TimezoneUTC only
Minimum intervalOnce per minute
Max cron triggers3 per Worker (free), more on paid plans
CPU time10ms (free) / 30s (paid) per invocation
AccuracyVery reliable — runs at the edge

Cross-Platform Comparison

FeatureGitHub ActionsVercel CronCF Workers
TimezoneUTCUTCUTC
Min interval (free)5 min1/day1 min
Min interval (paid)5 min1/min1 min
ReliabilityMedium (can delay)HighVery high
Max execution time6 hours10s-900s10ms-30s
Config location.github/workflows/vercel.jsonwrangler.toml
Trigger handlerWorkflow YAMLAPI routescheduled() event

Common Timezone Pitfall

All three platforms use UTC exclusively. This is the most common source of bugs when setting up cron schedules. Here's a quick UTC conversion table:

Local TimeUTC OffsetCron (9 AM local)
US Eastern (EST)UTC-50 14 * * *
US Pacific (PST)UTC-80 17 * * *
Central Europe (CET)UTC+10 8 * * *
China (CST)UTC+80 1 * * *
Japan (JST)UTC+90 0 * * *

Remember: Daylight Saving Time shifts UTC offsets. EST (UTC-5) becomes EDT (UTC-4) in summer. Your cron jobs won't adjust automatically.

10 Copy-Paste Cron Expressions

Here are the most commonly needed schedules, ready to use on any platform:

# Every 5 minutes
*/5 * * * *

# Every hour at :00
0 * * * *

# Every day at midnight UTC
0 0 * * *

# Every day at noon UTC
0 12 * * *

# Weekdays (Mon-Fri) at 9 AM UTC
0 9 * * 1-5

# Every Monday at 8 AM UTC
0 8 * * 1

# Every 6 hours
0 */6 * * *

# First day of every month at midnight
0 0 1 * *

# Every 15 minutes during business hours (8-17 UTC)
*/15 8-17 * * 1-5

# Last day of month at 11 PM UTC (approximate)
0 23 28-31 * *

Validate any cron expression with our Cron Parser →

Frequently Asked Questions

What timezone do GitHub Actions cron schedules use?

GitHub Actions cron schedules always use UTC. There is no option to change the timezone. If you need a job to run at 9 AM Eastern Time, you must convert that to UTC (1 PM or 2 PM depending on daylight saving time) and use the corresponding cron expression.

What is the minimum interval for Vercel Cron Jobs?

On the Vercel Hobby (free) plan, the minimum interval is once per day. On the Pro plan, the minimum is once per hour. On the Enterprise plan, the minimum is once per minute. Vercel uses standard 5-field cron expressions.

Can Cloudflare Workers Cron Triggers run every second?

No. Cloudflare Workers Cron Triggers use standard cron expressions with a minimum granularity of one minute. For sub-minute scheduling, you would need to use Durable Objects with the alarm() API.

Try These Related Tools

ā°Cron Expression Parser
Ad Space

Related Articles

Docker Compose YAML Validation: 10 Common Syntax Errors and How to Fix Them

Stop wasting time on Docker Compose YAML errors. Learn to identify and fix the 10 most common syntax mistakes.