Workers

Cron and scheduler

The cron backbone is two workers. ultron-cron is the master firer for fixed-schedule platform jobs (reconciler, janitor, lifecycle emails). ultron-cron-scheduler reads dynamic schedule definitions from the app database and dispatches per-workspace recurring tasks at their configured times.

Updated today

Overview

At a glance
Master firer
ultron-cron
Dispatcher
ultron-cron-scheduler
Trigger style
Both use the edge runtime's native cron triggers
Webhook secret
Shared with the app for signed POSTs
Dispatched endpoint
POST /api/cron/<handler> on the app

Two workers

Static schedules vs dynamic schedules.

Concernultron-cronultron-cron-scheduler
Driven byFixed cron expressions in wrangler.tomlRows in the schedules table
Tick frequencyPer-handler (5 min, hourly, daily, ...)Every minute
What it firesPlatform jobs (reconciler, janitor, lifecycle emails)User-defined recurring tasks (scheduled agents, scheduled posts, scheduled crawls)
Modifiable at runtimeNo (wrangler deploy required)Yes (write to schedules table)
Multi-tenantNoYes

Worker shape

ultron-cron/wrangler.tomltoml
1name = "ultron-cron"
2main = "src/index.ts"
3
4# Each cron line maps to a handler key. The scheduled() handler dispatches.
5[triggers]
6crons = [
7 "*/5 * * * *", # reconciler (every 5 min)
8 "0 * * * *", # janitor (hourly)
9 "0 9 * * *", # lifecycle-emails (daily 09:00 UTC)
10]
11
12[vars]
13APP_BASE = "https://app.51ultron.com"
14WEBHOOK_SECRET_KV_KEY = "ultron-cron:webhook-secret"
ultron-cron-scheduler/wrangler.tomltoml
1name = "ultron-cron-scheduler"
2main = "src/index.ts"
3
4[triggers]
5crons = ["* * * * *"] # every minute
6
7[vars]
8APP_BASE = "https://app.51ultron.com"
9SCHEDULES_TABLE = "scheduled_tasks"

Schedule catalogue

What ultron-cron fires by default.

CronHandlerWhat it does
*/5 * * * *reconcilerWalks workspaces with stalled jobs, retries up to 3 attempts
0 * * * *janitorDrops expired sandbox sessions, cleans /work R2 snapshots older than 7 days
0 9 * * *lifecycle-emailsSends day-1, day-7, day-14, day-30 lifecycle emails based on user activity
15 * * * *metrics-rollupAggregates analytics_dataset rows into per-workspace daily counts
0 0 * * 0weekly-digestSends the weekly digest email to opted-in workspaces
Note
ultron-cron does not do work itself. Each handler is a thin HTTP POST to the app with a signed body so the actual logic lives where the rest of the platform lives.

Dispatch contract

The body each handler dispatch carries.

dispatch payloadjson
1{
2 "handler": "reconciler",
3 "firedAt": "2026-05-19T12:05:00Z",
4 "nonce": "<sha256-derived>",
5 "secret": "<HMAC of body + nonce signed with WEBHOOK_SECRET>"
6}

The app verifies the HMAC, idempotency-checks the nonce against a short-lived KV cache, and runs the handler. On failure it returns 5xx; the cron worker retries up to twice with exponential backoff before logging a warning to the analytics dataset.

File map

cf-workers/ultron-cron
wrangler.toml
src
index.tsscheduled() dispatcher + fetch() webhook receiver
dispatch.tssigned POST helper
cf-workers/ultron-cron-scheduler
wrangler.toml
src
index.tsscheduled() reads schedules + dispatches