Decision
New crons, queues, schedulers and heavy or long-running backend work belong on Cloudflare: Workers Cron Triggers, Queues, Workflows and Durable Objects. Do not add them as Vercel Cron entries, Next.jsafter() continuations, new
/api/cron processor routes, pg_cron jobs, Supabase Edge Functions or Trigger.dev
tasks. This applies to all new services and to every legacy owner as it migrates.
Supabase remains the system of record. The rule moves compute and scheduling,
not data: Workers keep using the existing Supabase tables, RPCs, claims and RLS
through injected credentials. It does not authorize a database migration, a new
datastore or a production cutover.
Every Cloudflare job must meet the
runaway-work and cost acceptance
rules: bounded work and retries, idempotent progress, no rescheduling after a
terminal state, and a tested durable stop fence. Usage alerts and CPU limits are
not spending caps.
Choose the Cloudflare primitive
The background work inventory maps
every current owner to its target and cutover class. Reuse Cron Control for
recurring jobs instead of adding another controller for the same work. Preserve current cadence when moving a schedule; changing it needs
job-specific evidence and a product decision.
Shrink-only guard
scripts/ci/cloudflare-backend-ownership.test.js runs in the root script suite
and fails when a new owner appears outside Cloudflare:
A migration after the rule’s cutoff (
20261023000000) may not call
cron.schedule, even for an allowlisted name, except to re-tune a justified
retained Postgres job. A changed cadence is a new owner. Tests, paused runtimes
and the guard’s own files are excluded.
scripts/ci/cloudflare-backend-ownership-allowlist.js records each legacy owner
with its owner, Cloudflare target and plan. The test pins the adopted baseline;
entries may be removed but never added. Removing a legacy definition without
removing its entry fails as stale, so the list shrinks with each migration.
Retained Postgres exceptions
pg_cron may keep a job only when it is pure in-database maintenance: a single SQL statement against Postgres tables with no HTTP, storage or provider side effects, where a Cloudflare trigger would add a Worker invocation and a service-key round trip to run the same SQL in the same database. Each retained job carries its justification in the allowlist; jobs usingpg_net are not exceptions. New
exceptions are not admitted through the guard: schedule new work from Cloudflare.
Regression evidence
The guard test covers the repository scan, allowlist metadata, the frozen baseline, new and re-cadenced Vercel crons, catalog enablement, stale entries, post-cutoff migrations, unschedule replay, SQL comments/quoting/PL/pgSQL parsing, Edge Function source and configuration, Trigger.dev configuration/dependencies/imports, Nextafter() imports and new cron routes. It does not certify hosted schedules,
processor behavior or spend; those remain per-job cutover evidence.