jobs
Background work with retries, and crons.
"bindings": { "JOBS": "jobs" }await env.JOBS.send({ email: "[email protected]" }) // {id}
await env.JOBS.send({ report: 7 }, { delay: 3600, attempts: 5 }) // seconds; 3 attempts by default
await env.JOBS.send({ order: 42 }, { key: "receipt:42" }) // {id, duplicate: true} if one is pending
await env.JOBS.cancel(id) // or cancel("receipt:42"): true if it was queuedHandling jobs
Each job calls the service's job(job, env, ctx) with
{id, payload, attempt, cron}:
export default {
async fetch(request, env) { /* … */ },
async job({ payload, attempt }, env) {
await sendEmail(payload.email)
},
}A handler that throws is retried with backoff (10 s, 20 s, 40 s and so on, up
to an hour) until it runs out of attempts; then the job is dead. A job runs
up to 15 minutes, up to 4 at once per service.
Keys
A key (up to 256 bytes) makes a job the only one with it while it is
queued, running or dead: sending another returns that job's id with
duplicate: true and queues nothing. Once it is done or deleted, the key is
free again. cancel deletes a queued job; a running one finishes.
Crons
crons in the deployment queue a job each time the schedule matches: five
fields, in UTC.
"crons": [
{ "schedule": "*/15 * * * *", "payload": { "task": "sync" } },
{ "schedule": "0 9 * * 1-5", "payload": { "task": "digest" } }
]The job has the cron's payload, and cron set to its schedule. Cron jobs
have one attempt.
Limits
Payloads up to 256 KB; delays up to 30 days; up to 20 attempts. A service holds up to 10,000 jobs, queued and dead: past it, sending one fails until some run or are deleted. Dead jobs are kept 7 days (a cron's, 1 day: its next run is its retry), then deleted.
From the API
GET /api/services/<name>/jobs?status=dead → queued, running or dead
POST /api/services/<name>/jobs {"payload": ..., "delay": 0, "key": ""}
DELETE /api/services/<name>/jobs/<id> → deletes a job in any state
POST /api/services/<name>/jobs/<id>/retry → a dead job, with fresh attempts
POST /api/services/<name>/crons/run {"schedule": "0 * * * *"} → queues that cron's job now