Comparison

Crontap vs Cloudflare Workers Cron

Cloudflare Cron Triggers are perfect for one Worker. They get scratchy when you have eight Workers across three zones, each with its own wrangler.toml, all running on UTC, and any cadence change ships through a deploy. Crontap puts every Worker's schedule in one dashboard and decouples the cron from the code release.

At a glance

Cloudflare Workers Cron vs Crontap, side by side.

Cloudflare Workers Cron vs Crontap, dimension by dimension
DimensionCloudflare Workers CronCrontap
Schedule declared per WorkerYes (`wrangler.toml`)No (one dashboard, all Workers)
Per-IANA timezone per scheduleNo (UTC only)Yes
Cadence change without deployNo (`wrangler deploy`)Yes (dashboard save)
1-minute cadenceYes (1-min minimum)Yes (Pro)
Cross-zone / cross-account viewPer-zone dashboardsSingle account view
Cross-platform cron (non-Worker targets)NoYes (any HTTP endpoint)
Retries on 5xxNo (manual)Yes (automatic)
Failure alerts (email / Slack / Discord)Build it yourself in the WorkerOut of the box
Starting paidBundled with Workers plan$3.25/mo annual flat

How they work

The two approaches in one paragraph each.

Cloudflare Workers Cron

Cron Triggers are declared in `wrangler.toml` under `[triggers] crons = [...]` and the Worker exports a `scheduled` handler. Cloudflare runs the handler in the same isolate as the Worker's `fetch` route. As of 2026 the minimum cadence is 1 minute. Schedules are UTC only; per-Worker; cadence changes ship through `wrangler deploy`.

Crontap

Crontap calls your Worker's `fetch` route on the cron schedule. The Worker keeps its `fetch` handler; the `scheduled` handler is gone. You get one dashboard across every Worker in every zone, plus every non-Worker target (Lambda Function URL, Cloud Run service, Vercel API route) you also happen to schedule. Cadence changes are dashboard saves.

Where each side wins

Honest broker, both columns.

Cloudflare Workers Cron wins on

  • Free and native if you have only one Worker — no external dependency.
  • Schedules ship in the same git commit as the code; no drift between repo and dashboard.
  • Runs inside the same isolate as the Worker, so cold-start cost is the Worker's normal cold start.
  • Good fit when the Worker exists primarily to run on a cron.

Crontap wins on

  • Single dashboard across every Worker in every zone (Cron Triggers are per-`wrangler.toml`, per-zone).
  • Per-IANA timezone per schedule — no DST math, no twice-a-year cron edit, no UTC-to-Berlin mental arithmetic.
  • Cadence change without a deploy. Want to bump the cache-warm from every 5 minutes to every 2 minutes for a week of high traffic? It's a dashboard save, not a Worker deploy.
  • Schedules survive when a Worker is paused, redeployed, or moved between zones; the trigger is external.
  • Retries on 5xx and stored response bodies. Cron Triggers don't retry, and failures are whatever logging you've wired up in the Worker.
  • Failure alerts to email / Slack / Discord / Telegram on the schedule's Integrations panel.
  • The same dashboard fires non-Worker targets too: an AWS Lambda Function URL, a Cloud Run service, a Vercel API route.

The math

Cadence and pricing, worked out.

  • Cron Triggers are bundled with the Workers plan: free tier covers a baseline of triggers per day; the Workers paid plan ($5/mo for the Standard plan as of 2026) covers more invocations.
  • Crontap Pro is $3.25/mo annual flat for unlimited HTTP schedules at minute cadence (covering Workers and non-Workers targets in the same bill).
  • If your only schedules are inside one Workers account and you have free-plan headroom, Cron Triggers cost nothing. The pricing wedge is the dashboard, not the dollar.

Moving from Cloudflare Workers Cron

The migration, in 6 steps.

  1. For each Worker with a `scheduled` handler: refactor the body into a function you can call from `fetch` too.
  2. Add a `fetch` route (e.g. `/__crontap/run`) that checks a bearer header and calls the refactored function.
  3. Create a Crontap schedule against `https://<worker>.<account>.workers.dev/__crontap/run` using the same cron expression. Add the IANA timezone you actually want.
  4. Verify the Crontap run log matches the Cron Trigger log for one cycle (Workers Trace Events vs the Crontap dashboard).
  5. Remove the `[triggers]` block and the `scheduled` handler. Deploy.
  6. Repeat for every Worker with a Cron Trigger. The Crontap dashboard now lists every schedule in one place.

Decision

Which one fits.

Pick Cloudflare Workers Cron if

You have one Worker, the schedule is its primary purpose, you're happy with UTC, and cadence changes ride along with your normal deploy cadence.

Pick Crontap if

You have several Workers across zones, you need per-IANA timezones, you want to retune cadence without a deploy, or you also schedule non-Worker targets.

Pair both if

Use Cron Triggers for the rare Worker whose entire purpose is one schedule. Use Crontap for everything else, including the cross-platform jobs that Cron Triggers can't reach.

FAQ

Crontap vs Cloudflare Workers Cron, in detail.

Can Crontap call a Worker on a `workers.dev` URL?
Yes. Workers expose `fetch` natively; Crontap calls that URL on the cron schedule with a bearer header. The Worker runs in the same isolate as any normal request. The `[triggers]` block in `wrangler.toml` becomes irrelevant.
Will I lose anything by dropping the `scheduled` handler?
The `scheduled` event has a slightly different invocation context than `fetch` — no `Request` object, longer wall-clock budget. For most cron-style work that doesn't matter. If you specifically depend on the scheduled event's properties, keep the Cron Trigger and add Crontap only for the cross-Worker dashboard view.
What about Workers in multiple zones or accounts?
That's the main reason teams move. Cron Triggers live in the zone where the Worker is deployed; there's no cross-zone dashboard. Crontap shows every schedule across every zone in one list, sorted by next-fire time.
Does this work with Durable Objects or KV bindings?
Yes. The Worker's runtime (Durable Objects, KV, R2 bindings, secrets) is unchanged. Only the trigger layer moved from `scheduled` to `fetch`. Inside the handler you still have access to `env` and the same bindings the Worker had before.

Sources

Ready to fix it?

Point Crontap at any URL. Pick any cron. Done.

WordPress, Shopify, Railway, Cloud Run, Vercel, HubSpot, Ghost, your own box. If it answers HTTP, Crontap can drive it on a clock you can read, in the timezone that actually matters, and page you when something breaks.

Free forever tier ・ No credit card required

GET

/wp-cron.php?doing_wp_cron=1

Running
Your next schedule

Schedule

"every 5 minutes"

Next

in 23s