Cloudflare, in pieces
Chapters

Cloudflare / 04

Work that outlives
the request.

A caption takes longer than a visitor should wait, and it can fail. So the request enqueues a command and answers. Then the message is delivered, maybe twice, and a workflow remembers how far it got.

2 instruments · A drawer on waitUntil() · Sources and limits

Illustration Delivered twice

Queues deliver at least once, in no guaranteed order. If the consumer saves a caption and then fails before the batch is acknowledged, the message is delivered again. A consumer that applies every delivery saves the caption twice. One that checks the command ID and records it in the same transaction as the effect commits it once and rejects the second delivery. An acknowledged message is not redelivered even if the batch fails later; otherwise the whole batch is retried, by default three times, and then the message is deleted or sent to a dead-letter queue.

Illustration A process that remembers

The consumer starts a Workflow: read input, call the model, sleep until tomorrow, store the result. When the model step fails, it is retried, and the read step’s recorded result is reused, not re-run. While the workflow sleeps no step runs, and the engine can hibernate, so a variable kept outside the steps is lost; the results recorded by the steps are not.

A retried step may repeat its side effects, so steps should be idempotent. Step names are the key a result is recorded under; build state from step results, not from variables outside them.

waitUntil() is not a job system

ctx.waitUntil(promise) lets a Worker answer and keep running until the promise settles, up to a documented limit after the response. Work still running then is cancelled. Nothing records it, retries it, or reports that it failed, so it suits work you can lose: an analytics event, a copy into a cache. Work that matters goes to a queue or a workflow.

Read the mechanism

Queues

A producer sends a message and moves on; a consumer receives messages in batches. Delivery is at least once and unordered. When a message in a batch fails, the whole batch is retried unless messages were acknowledged one by one. Put a command ID in the message and record it with the effect, in one transaction; an ID the consumer never checks protects nothing. Idempotency does not make repeated deliveries disappear: it makes them harmless.

Workflows

Your code names each step with step.do(), and a finished step’s result is kept. step.sleep() and step.sleepUntil() pause for time; step.waitForEvent() pauses for an event. Any Worker can call create() on the binding; the queue in front of the workflow here is a choice, not a requirement.

Alarms, Workers AI and Vectorize

A Durable Object can set one alarm at a time; its handler runs at least once (chapter 03 fires one). Workers AI runs a model outside the Worker’s isolate, and its output can be wrong. Vectorize searches embeddings a model made; it makes neither embeddings nor answers.

Sources and limits

Cloudflare pages used

Documented and illustrated

Left out on purpose