System flow
The whole console in one picture: who calls it, what the Worker checks, where the data goes, and how a call to a target ends. Under it are a task's life and a job's run, step by step.
- Three callers: the console pages, static assets that call /api with a person's session; apps, which call /v1 with a project API key; and the cron trigger, every minute.
- They all reach one Worker, cloud-console. It matches the route, checks the session (and its CSRF token on a change) or the API key, and checks the permission in the project.
- The Worker reads and writes D1: users, projects, keys, the audit log, queue and job definitions, and run logs.
- It hands tasks to a QueueObject, one per queue. The object keeps its pending tasks in its own SQLite, sets an alarm at the next due time, and dispatches each task to its target URL.
- It tells a JobObject, one per job, the job's cron and time zone. At the alarm for the next run, the object calls the target URL, or adds a task to a queue's object.
- Each call to a target URL ends in one of two ways. A 2xx answer is done. Anything else is retried with backoff; when the attempts or the retry time run out, or the status is one never retried, the task or run is Failed.
- Around it: alerts go by email and to Google Chat, and once a day at 02:20 UTC the cron backs D1 up, sealed and signed, to a B2 bucket.
How it fits together
Three kinds of caller. A request for a console page is answered from the static assets, so it never runs the Worker. The page then calls /api with the person's session cookie. Apps call /v1 with their project's API key. Once a minute the cron trigger runs the Worker's scheduled parts.
One Worker checks every call. Each route says who may call it: anyone, a signed-in person, or an admin. A change from a person needs the CSRF token and must come from the console's own pages. A project route first checks the person's permission in that project. A /v1 route checks the key, and a key reaches only its own project.
D1 holds what the pages list and edit; the objects hold the work. Saving a queue or a job writes its definition to D1, then tells its Durable Object. A QueueObject, named <project>/<queue>, keeps the queue's pending tasks in its own SQLite and applies the queue's rate, concurrency and retry settings. A JobObject keeps one job's schedule. Each sets an alarm for its next piece of work, and both write their run logs to D1.
The cron is the safety net. It wakes any queue or job whose alarm should have fired. Its other parts prune old rows, rotate the signing keys, and run the daily backup a few steps a minute.
Only a 2xx answer succeeds. Redirects are not followed. Any other answer, or none within the attempt deadline, is tried again with backoff until the attempts or the retry time run out. An answer that will never succeed (400, 401, 403, 404, 410 and 422 by default) fails at once.
A task's life
Each step runs only when the one before it passed. Beside each step is what stops it or holds it.
-
CreatedOn the Create a task page (one task, or up to 50 from a file), or by an app through
/v1. The Worker checks the sign-in or the key, the permission, every field, the secrets and service accounts the task names, and the project's daily quota. Then it hands the task to its queue's object.400 with a message for each field; 409 for a task name the queue still remembers; 429quotawhen the day's cap is used up. Nothing is added. -
WaitingThe queue's object keeps the task in its own SQLite, with its headers and body sealed, and sets its alarm for the next due time. A task may be scheduled up to 30 days ahead.Held, not lost: a paused queue, a maintenance switch or the free-plan hold keeps tasks waiting. Near a free limit, low-priority queues are held first.
-
SentAt the alarm, the object sends the due tasks within the queue's max dispatches per second and max concurrent dispatches. Before each attempt the target's host is resolved and checked, and the auth header is added. The attempt deadline is 3 minutes unless the task sets one, and 15 minutes at most.A private or blocked address, or a credential not allowed at that origin, fails the attempt and nothing is sent.
-
RetriedA failed attempt (408, 429, 5xx, a timeout or a network error) is tried again. The wait starts at min backoff, doubles max doublings times, then grows linearly, never above max backoff. A
Retry-Afteranswer delays the next try, up to max backoff. Each retry counts against the daily quota; one with no room left waits for the next UTC day.Not retried: a status in the queue's never-retried list (400, 401, 403, 404, 410 and 422 by default) fails the task at once. -
Succeeded or failedA 2xx answer ends the task as succeeded. It fails for good when max attempts are used (100 by default), when the next try would come after max retry duration, or at a status that is never retried.Succeeded: its headers and body are deleted, and the queue remembers its name for 24 hours.Failed: kept 7 days on the Failed tab, to retry or delete. An alert goes out when the project has it on, and a copy goes to a dead-letter queue when one is set.
A job's run
-
CreatedCreate a job takes three steps: the schedule (unix-cron and a time zone, with the next five runs shown), the target (an HTTP call, or a task for one of the project's queues) and the optional settings. The Worker saves the job to D1 and tells its
JobObject, which sets an alarm for the next run. The job starts enabled.400 with a message for each field; 409 for a name taken, or when the project has its 200 jobs. -
The alarm firesWithin a minute of the scheduled time; the every-minute cron wakes a job whose alarm should have fired. A local time that a daylight-saving change skips does not run that day, and one that happens twice runs once.Skipped and logged: while maintenance is on; inside quiet hours when the job skips them; while an earlier run is still going and overlap is skip, the default. A paused job has no next run.
-
It counts, then callsEach run counts once against the project's daily quota. An HTTP target is called as a task is, within the job's attempt deadline (3 minutes by default). A queue target adds a task named after the job and the scheduled time, so a run cannot add it twice; the queue's settings then retry that task.Over the quota: a scheduled run is skipped and logged, and Force run answers 429
quota. -
RetriedA failed attempt is tried again up to the job's max retry attempts (0 to 5, and 0 by default), with its own backoff: 5 seconds at first and at most 1 hour, by default.A status in the job's never-retried list ends the run at once. While maintenance is on, a run under way waits to retry.
-
LoggedThe run's time, status code, duration, attempt and error go to the job's Logs. The Jobs list shows the last run's status and the next run.Success.Failed, with its status code. After 2 failed runs in a row (the project's alert setting), an alert; another when the job recovers.
Cloud Console, as it is on main. 22 Oct 2026.