State and background work
Run scheduled maintenance
Add a scheduled handler for bounded cleanup work and test it without relying on an incoming HTTP request.
8 minute lesson
Cron Triggers invoke a Worker’s scheduled handler according to configured UTC schedules.
Use schedules for periodic tasks such as deleting expired export metadata in bounded batches. Keep the job idempotent, log a safe summary, and store progress if it cannot finish within one invocation.
export default {
fetch: app.fetch,
async scheduled(event: ScheduledEvent, env: Env, ctx: ExecutionContext) {
ctx.waitUntil(deleteExpiredExports(env))
}
}
Schedules are expressed in UTC and are delivery triggers, not precise wall clocks. A run can be delayed or overlap a previous run, so cleanup must be safe to repeat. Use a stable cutoff passed into the operation and delete a bounded page of rows rather than scanning the entire dataset in one invocation.
If more work remains, store a cursor or enqueue the next bounded unit. Include the scheduled timestamp, cursor, deleted count, and error class in logs. Test the handler directly with a fixed clock and fixtures on both sides of the cutoff; waiting for the next real cron event is not a useful development loop.
Add a local scheduled test that removes expired rows but preserves active exports.
Lesson completed