Bindingsjobs
Bindings

jobs

Background work with retries, and crons.

json
"bindings": { "JOBS": "jobs" }
js
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 queued

Handling jobs

Each job calls the service's job(job, env, ctx) with {id, payload, attempt, cron}:

js
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.

json
"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

http
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