Skip to content
Back to Cloud Services

Cloudflare Cron Triggers

Scheduled Workers via cron expressions — run cleanup, sync, and periodic jobs at the edge.

CloudflareBeginner

Why

Cron Triggers run Workers on a schedule without a server — free, no EventBridge cost, and execute at the edge near your data. Up to 5 cron expressions per Worker.

Cloudflare's network spans 330+ cities in 125+ countries, serving 20% of all internet traffic. Workers have 0ms cold starts (isolate-based) and the free tier covers 100k requests/day.

When

Use for nightly DB backups, hourly cache warming, daily report generation, and token refresh. Avoid for jobs >30s CPU (Workers limit) or needing complex orchestration.

How

1. Add to wrangler.toml — [triggers] crons = ["0 * * * *", "0 2 * * *"] 2. Implement — export default { async scheduled(event, env, ctx) {...} } 3. Test — wrangler dev --test-scheduled triggers the handler 4. Deploy — wrangler deploy, schedule active immediately 5. Observe — dashboard → Triggers → Cron Events shows invocations + logs 6. Dynamic — use Durable Object alarms for runtime-defined schedules

Example

// wrangler.toml [triggers] crons = ["0 2 * * *"] # daily at 2am UTC // src/index.ts — nightly backup of D1 to R2 export default { async scheduled(event: ScheduledEvent, env: Env, ctx: ExecutionContext) { ctx.waitUntil((async () => { const { results } = await env.DB.prepare("SELECT * FROM users").all(); await env.BACKUP.put(`users/${new Date().toISOString().slice(0,10)}.json`, JSON.stringify(results)); })()); }, async fetch(request: Request, env: Env) { return new Response("HTTP handler still works alongside cron"); }, };

Common Problems

  • ⚠Cron in UTC only — no timezone support, convert local time to UTC expression
  • ⚠Max 5 crons per Worker — need more? Split across multiple Workers
  • ⚠No retry on failure — scheduled handler must self-retry via Queues on error

Best Practices

  • ✓Use ctx.waitUntil for async work — ensures cron handler doesn't terminate early
  • ✓Idempotent cron jobs — same job twice = same result, safe for retries/duplicates
  • ✓Log start/end + duration — cron failures are silent without explicit logging

FAQ

What is Cloudflare Cron Triggers and what problem does it solve?

Scheduled Workers via cron expressions — run cleanup, sync, and periodic jobs at the edge. It lets developers deploy, store, and scale without self-managing infrastructure — a core reference for cloud service selection.

How do I get started with Cloudflare Cron Triggers in 5 minutes?

Two steps to run it: (1) Add to wrangler.toml — [triggers] crons = ["0 * * * *", "0 2 * * *"]; (2) Implement — export default { async scheduled(event, env, ctx) {...} }. Validate on the free tier first, then wire into production.

What is the #1 pitfall with Cloudflare Cron Triggers?

The most frequent issue is: Cron in UTC only — no timezone support, convert local time to UTC expression. Run a pre-launch checklist item by item, and add policy/config scanning in CI.

What are the best practices for Cloudflare Cron Triggers?

Best practices for Cloudflare Cron Triggers include: Use ctx.waitUntil for async work — ensures cron handler doesn't terminate early; Idempotent cron jobs — same job twice = same result, safe for retries/duplicates; Log start/end + duration — cron failures are silent without explicit logging. The first one — "Use ctx.waitUntil for async work — ensures cron handler doesn't terminate early" — should be a team default baked into your IaC templates.

How do I control cost and avoid bill surprises with Cloudflare Cron Triggers?

Three ways to prevent overspend: (1) tag every resource with env/team and enable billing alarms; (2) set budget thresholds to trigger Slack/email alerts; (3) review idle resources in Cost Explorer regularly and clean them up. Most Cloudflare Cron Triggers options offer a free tier — validate within free quota before scaling.