Choose Durable Objects for single-identity state, queues for deferred work, and the binding guides for the mechanics
Use Durable Objects when one identity should own state or coordination. Use queues when work should happen later, in batches, or with retries. Then open the specific binding guide once the pattern is clear.
This page is the pattern chooser for stateful or deferred work. It should help you decide when a Durable Object, a queue, or a mix of both fits the job without turning into a duplicate reference page for either binding.
- Best for
- Choosing between stateful identities, background work, or a mix of both
- Choose by
- State ownership vs deferred work ownership
- Best local proof
- One real object call or one real queue trigger through the default harness
- Preview warning
- Durable Object-heavy previews and queue-owned resources have different release questions
Choose the primitive by ownership, not by vibes
The decision is easier when you ask who owns the work. If one stateful identity should serialize and own it, that points toward Durable Objects. If the request can accept the work and let something else finish it later, that points toward queues.
Once that choice is made, the specific binding guide should take over so this page does not try to restate every authoring and testing rule for both bindings.
| Pattern | Reach for it when | Usually the wrong fit |
|---|---|---|
| One identity should own state, coordination, ordering, alarms, or WebSocket-adjacent behavior. | The work is fire-and-forget, batchable, or mainly about retries. | |
| The request can enqueue work and return while a consumer handles retries, batching, or slow follow-up tasks. | The user needs the state transition to finish synchronously in the request path. | |
| A request or Durable Object owns the immediate state, then enqueues slower side work such as email, indexing, or downstream writes. | One primitive already tells the whole story and the second one would only add ceremony. |
The point is pattern fit, not duplicate reference docs
If you already know you need a Durable Object or a queue, the binding guide is the next page. This page is here for the choice, not the full mechanics.
Keep the config shapes explicit once you know the pattern
Both patterns work better when the binding contract is visible in config. Durable Objects should name the object classes or refs clearly, and queues should keep producers, consumers, and dead-letter rules in one authored shape instead of hiding them in deployment-only conventions.
Durable Object binding authoring should stay boring and explicit
Queue config should keep producer and consumer ownership visible
Testing and preview questions are different for the two patterns
Ship & operate
Preview strategies
Preview caveatsOpen this when the real question is how Durable Objects or preview-scoped queue resources change the preview model.
Testing
Testing overview
MapUse the testing map when the next question is about the right harness or which docs own the testing guidance.
- Durable Object tests are best at local object behavior, identity lookup, and stateful coordination. They do not replace migration or preview-topology checks.
- Queue tests are best at direct consumer behavior, retries, batching, and side effects through . They do not replace preview resource lifecycle checks.
- Durable Object-heavy preview flows deserve extra care because same-worker preview URLs and migrations have real platform caveats.
- If the real question is no longer “which primitive fits?” switch to the binding guide or the preview docs before this page starts repeating them badly.
Open the binding guide once the pattern is obvious
Previous
R2 uploads & delivery
Use presigned URLs for direct uploads, public buckets on custom domains for truly public assets, and private buckets plus Worker auth for protected files. Keep out of production, and when a preview or environment needs its own bucket, scope it intentionally instead of borrowing production storage.
Next
Worker composition
Use this page for the architecture question: when a separate worker boundary is justified, how and service bindings keep it explicit, and where local tests and release checks should prove the wiring.