SYSTEM Cited by 14 sources
Cloudflare Durable Objects¶
Durable Objects (DO) is Cloudflare's
globally-addressable, single-writer, stateful actor primitive on
top of Workers
(developers.cloudflare.com/durable-objects).
Each Durable Object has an ID; Cloudflare routes all traffic
for that ID to exactly one instance at a time, providing
strong consistency and serialized access to embedded storage.
Role¶
- Actor-style stateful compute on the edge: one instance per key, guaranteed single-writer semantics.
- Embedded transactional storage per object.
- Natural fit for coordination, session state, collaborative documents, agent state machines.
- Used inside Cloudflare's own internal AI stack for agent runtime — see sources/2026-04-20-cloudflare-internal-ai-engineering-stack.
Local / remote parity¶
Durable Objects are among the bindings introspectable via
Local Explorer's API at
/cdn-cgi/explorer/api, backed by
Miniflare-managed local instances and
on-disk state (Source:
sources/2026-04-13-cloudflare-building-a-cli-for-all-of-cloudflare).
The API shape is identical between local and remote; --local
flag on cf or
Wrangler is the only routing difference.
As a credentialed-proxy boundary (Agent Lee, 2026-04-15)¶
Cloudflare's Agent Lee uses a Durable Object as the permission-enforcement layer between an LLM-driven sandbox and Cloudflare's MCP server. The DO inspects generated code, classifies it read vs write, proxies reads directly, and blocks writes until the user approves via a dashboard elicitation gate. API keys are held inside the DO and injected server-side — they are never present in the sandbox. This is the canonical wiki instance of patterns/agent-sandbox-with-gateway-only-egress — the DO's per-key single-writer + embedded-storage primitives are load-bearing (scoped credential state, deterministic classification logic co-located with the gate).
As the agent-actor substrate (Project Think, 2026-04-15)¶
Published the same day as the Agent Lee launch, Cloudflare's Project Think positions Durable Objects as the explicit actor-model substrate for AI agents. "Each agent is an addressable entity with its own SQLite database. It consumes zero compute when hibernated. When something happens (an HTTP request, a WebSocket message, a scheduled alarm, an inbound email) the platform wakes the agent, loads its state, and hands it the event."
The comparison table from the post, reproduced:
| VMs / Containers | Durable Objects | |
|---|---|---|
| Idle cost | Full compute cost, always | Zero (hibernated) |
| Scaling | Provision + manage capacity | Automatic, per-agent |
| State | External DB required | Built-in SQLite |
| Recovery | You build it | Platform restarts, state survives |
| Identity / routing | You build it | Built-in (name → agent) |
| 10,000 agents × 1% active | 10,000 always-on | ~100 active at any moment |
This economic framing is the load-bearing scaling premise that drives the entire Project Think substrate.
Project Think exposes three DO-substrate-hosted primitives as first-class SDK APIs on top of the base Agent:
- Durable execution via fibers —
runFiber("name", async (ctx) => { … })registers a durable function invocation in the agent's SQLite;ctx.stash()checkpoints;onFiberRecovered()resumes after eviction / restart / deploy. See concepts/durable-execution, checkpoint-resumable-fiber. - Sub-agents via Facets —
this.subAgent(ChildClass, "name")returns a child DO colocated with the parent via Facets, each with its own isolated SQLite. "Sub-agent RPC latency is a function call. TypeScript catches misuse at compile time." See colocated-child-actor-rpc. - Persistent sessions — tree-structured conversation memory stored in DO SQLite with FTS5 full-text search, non-destructive compaction, and forking. See tree-structured-conversation-memory.
Context blocks (structured system-prompt sections the model can read + update, persisted across hibernation) also live in DO storage.
As a single-threaded host for native Rust servers (Pumpkin, 2026-09-28)¶
The DO's "exactly one thread" property is usually framed as a consistency
guarantee; the 2026-09-28 Emscripten-target post exercises it as a native-server
host. Dan Lapid ported Pumpkin, a Tokio-based Rust
Minecraft server "designed for multi-core machines", into a Durable Object over a
single weekend. Because a DO has one thread, Pumpkin's dedicated OS threads had to
become cooperative tasks on the event loop: the tick loop + chunk scheduler
became async tasks, each Rayon job became a Tokio task, and world generation runs on
the event loop itself — "taking one turn per chunk and interleaving with network
I/O and game ticks rather than blocking them." This leans directly on Cloudflare's
Tokio event-loop-integration work (JSPI / LocalEventLoop; see systems/tokio).
Two DO primitives are load-bearing:
- SQLite storage as a filesystem. Pumpkin persists its world through ordinary
std::fs; under Emscripten's-sNODERAWFS, FS calls forward to thenode:fsNode.js compat layer, and worker-fs-mount mounts anode:fs-compatible FS whosedurable-object-fsbackend stores every file as a row in the DO's SQLite storage, written synchronously and committed with the DO's transaction. "Pumpkin itself has no idea it isn't on disk, and a restarted object boots straight from the same world." A clean instance of the DO's embedded transactional storage standing in for a POSIX filesystem. - The DO as the TCP-server container. Each player's connection arrives through
Workers TCP ingress at the Worker's
connect()handler and is forwarded into the DO, wherehandleAsNodeConnection()fromcloudflare:nodedispatches the socket to anet.Serverlistening on that port inside the object (the TCP counterpart ofhandleAsNodeRequest()).-sNODERAWSOCKETSimplementsTcpListeneron top ofnet.Server; the returned promise tells the object when the last player left so it can save and shut down.
"Running a fully persistent Minecraft server inside a Durable Object with multiplayer support demonstrates the level of native compatibility that is possible with this new Emscripten target." (Source: sources/2026-09-28-cloudflare-supporting-native-rust-in-workers-with-the-new-emscripten-target)
As the explicit Container controller (ctx.container, 2026-09-30)¶
Cloudflare's 2026-09 Containers rearchitecture makes the Durable Object the
explicit controller of its attached Container, exposed natively on
this.ctx.container with no wrapper class in between (Source:
sources/2026-09-30-cloudflare-containers-rebuilt-to-scale-agent-sandboxes).
Under the durable_object scheduling policy, the DO chooses each sandbox's
image and instance type at request time
(ctx.container.start({ image, instance, enableInternet })), and exec(),
outbound-request interception, runtime image/instance selection, and filesystem
snapshots all live on ctx.container. This makes the Container a compute
extension of the DO: the Container supplies the Linux environment while the DO
retains identity, state, policy, and lifecycle.
Load-bearing consequences of this coupling:
- Scheduler locality. Demand begins at the DO, so the scheduler looks for Container capacity on the machine the DO is already running on first — a primary reason first-command startup dropped ~6× (see Containers and concepts/cold-start).
- Rollout as DO code. Image selection at start time means canary/pin/
migrate/rollback are ordinary DO logic (hash
ctx.id, readpinned-imagefrom DO storage) rather than a platform config push (patterns/progressive-configuration-rollout). - Programmable egress boundary. The DO can remember which services/repos/ operations a user authorized and update the Container's Outbound Request Handler to inject credentials and enforce policy — the Cloudflare OS Gatekeeper pattern per agent computer (patterns/central-proxy-choke-point, patterns/agent-sandbox-with-gateway-only-egress).
- Brain/hands split. Run the agent loop in the DO (session state, WebSockets, model calls) and wake the Container only for a shell/compiler/ dev-server, stopping Linux compute while idle (concepts/scale-to-zero); or run the agent in the Container and supervise from the DO (patterns/specialized-agent-decomposition).
This supersedes the earlier model where the DO was deliberately hidden behind
the Sandbox SDK Container class; that class
is maintained only through 2026-12-31, and Sandbox SDK 1.0 is reframed as
utilities usable inside your own DurableObject class.
Seen in¶
- sources/2026-09-30-cloudflare-containers-rebuilt-to-scale-agent-sandboxes
— canonical wiki instance of the DO as the explicit, native controller of
its Container via
ctx.containerunder thedurable_objectscheduling policy: runtime image/instance selection, rollout-as-code, DO-local scheduler placement (6.2× startup), programmable Outbound Request Handler, and DO-owned snapshot lifecycle. Makes the Container a compute extension of the DO. -
sources/2026-09-28-cloudflare-supporting-native-rust-in-workers-with-the-new-emscripten-target — canonical wiki instance of a DO as the single-threaded host for a native Rust (Tokio) server. Pumpkin's OS threads collapse to cooperative event-loop tasks; the DO's SQLite storage backs a
node:fs-compatible world filesystem viaworker-fs-mount; the DO holds the in-objectnet.Serverreached viahandleAsNodeConnection()+-sNODERAWSOCKETS+ Workersconnect()TCP ingress. -
sources/2026-05-13-cloudflare-browser-run-now-running-on-cloudflare-containers-its-faster — canonical wiki instance of DO + Container as a paired primitive with placement decoupling as the primary asymmetry. DO-enabled Cloudflare Containers create a Durable Object near the request, but the connected Container "may spin up on the other side of the world" — for chatty multi-message workloads (e.g. headless-browser control over WebSocket) the cross-region distance is paid per-message (do-to-container-cross-region-rtt). Browser Run's response: pre-warmed regional pools of DO+Container pairs (regional-pre-warmed-do-container-pair-pool), selecting the "DO-container pair closest to the user within that region" at request time. First wiki instance of DOs treated as a half of a paired primitive whose placement is load-bearing for a chatty-RPC partner.
- sources/2026-04-21-planetscale-faster-planetscale-postgres-connections-with-cloudflare-hyperdrive — canonical "DO-not-on-write-path" datapoint. The Simeon Griggs 2026-02-19 PlanetScale × Hyperdrive prediction-market demo names the trade-off explicitly: "If we're going to use a Durable Object to broadcast updates over WebSockets, it may be tempting to make the Durable Object the write path to the database. However, this negatively impacts performance. Durable Objects are single-threaded and hosted in a single location, making them a bad candidate for the write path. Instead the Workers will send transactions to the database via the Hyperdrive connection." The DO in this architecture holds no authoritative state — only the WebSocket subscriber list. Writes go Worker → Hyperdrive → Postgres; on commit, the Worker "pings the Durable Object via the WebSocket connection to fan out that update to all other connected browsers". The post also flags the single-DO scaling ceiling and the canonical mitigation ("you can scale Durable Objects horizontally — sharded with a key"). Canonical wiki substrate for single-region-do-fanout-from-distributed-writers and the broadcast side of db-authoritative-with-websocket-notify.
- sources/2026-04-13-cloudflare-building-a-cli-for-all-of-cloudflare — one of the remote-or-local bindings the new CLI unifies.
- sources/2026-01-29-cloudflare-moltworker-self-hosted-ai-agent — used as the state layer for Moltworker's per-session agent state.
- sources/2026-04-20-cloudflare-internal-ai-engineering-stack — used inside Cloudflare's internal agent runtime.
- sources/2026-04-15-cloudflare-introducing-agent-lee — the credentialed proxy between LLM-generated code and the Cloudflare MCP server; classifies read vs write, hosts the elicitation gate, holds API keys so the sandbox never sees them.
- sources/2026-04-15-cloudflare-project-think-building-the-next-generation-of-ai-agents — positioned as the actor-model substrate for AI agents; the three SDK primitives (fibers, sub-agents via Facets, sessions)
- context blocks all live on DO storage. The "10,000 agents at 1% active" VM-vs-DO comparison quantifies the one-to-one-agent scaling premise.
- sources/2026-04-16-cloudflare-ai-search-the-search-primitive-for-your-agents
— DO-per-agent-session is the canonical consumer of the
AI Search
ai_search_namespacesbinding. The support-agent example'sSupportAgent extends AIChatAgentis a DO; creates a per-customer AI Search instance at session start (idempotenttry { create() } catch {}); exposessearch_knowledge_base+save_resolutiontools that fan out across shared + per-customer instances. DO-backed conversation-history + per-customer search-instance together realise agent memory at both the episodic and semantic tiers. - sources/2026-04-16-cloudflare-artifacts-versioned-storage-that-speaks-git
— one DO per Artifacts repo
is the load-bearing substrate of the versioned-storage tier
launched 2026-04-16. Each DO hosts a ~100 KB pure-Zig
Wasm Git server + embedded SQLite
(
state.storage.kv) holding Git objects chunked across rows (2 MB row limit); pack-file snapshots spill to R2; auth tokens in [[systems/ cloudflare-kv|KV]]. "The ability to create millions (or tens of millions+) of instances of stateful, isolated compute is inherent to how Durable Objects work today, and that's exactly what we needed for supporting millions of Git repos per namespace." Post calls out the ~128 MB DO memory budget driving streaming on fetch + push paths (ReadableStream<Uint8Array>from raw WASM chunks) and delta-form-alongside-resolved-object storage as the key memory-discipline moves. Canonical wiki instance of do-backed-git-server and the repo-per-session dogfood pattern (Cloudflare uses Artifacts internally to persist filesystem + session history in per-session repos — fork, time-travel, diff on arbitrary agent state). Fourth 2026-04 launch whose load-bearing primitive is "one DO per caller-identified unit" (alongside Agent Lee, Project Think, and AI Search). - sources/2026-04-16-cloudflare-email-service-public-beta-ready-for-agents
— one DO per email-address-resolved agent instance is the
load-bearing shape of the Agents
SDK's email surface (2026-04-16). The address-based resolver
parses
local+sub@domainand dispatches to a DO via{className: local, instanceName: sub}; embedded DO state (this.setState(...)) is the inbox's memory substrate — "the inbox becomes the agent's memory, without needing a separate database or vector store"; HMAC-SHA256-signedinReplyToheaders route replies back to the exact originating DO instance (signed-reply-routing-header). Fifth 2026-04 launch whose load-bearing primitive is "one DO per caller-identified unit" (alongside Agent Lee, Project Think, AI Search, and Artifacts). - sources/2026-04-17-cloudflare-introducing-flagship-feature-flags-built-for-the-age-of-ai — one DO per Flagship app as control-plane source of truth for the 2026-04-17 Flagship feature-flag service (private beta). Direct from the post: "the control plane writes the change atomically to a Durable Object — a SQLite-backed, globally unique instance that serves as the source of truth for that app's flag configuration and changelog. Within seconds, the updated flag config is synced to Workers KV, Cloudflare's globally distributed key-value store, where it's replicated across Cloudflare's network." Sixth 2026-04 launch whose load-bearing primitive is "one DO per caller-identified unit" (after Agent Lee, Project Think, AI Search, Artifacts, and Email Service) — but structurally distinct: Flagship is the first where the per-unit DO is explicitly paired with globally-replicated Workers KV as the edge-local read tier for the DO's data, because feature-flag evaluation must be zero-outbound-call in the same V8 isolate serving the request. Flagship is the canonical wiki instance of do-plus-kv-edge-config-distribution — DO as atomic-write source-of-truth with embedded audit-trail changelog, KV as eventually-consistent edge replica. The sibling pattern do-backed-git-server (Artifacts) uses KV differently — there KV holds auth tokens (a distinct read tier) while the per-repo DO holds the data; in Flagship KV holds the data (flag config) while the per-app DO holds the source-of-truth.
Related¶
- systems/cloudflare-workers
- systems/miniflare
- systems/cloudflare-local-explorer
- systems/cf-cli
- systems/project-think — SDK that layers fibers + sub-agents
- sessions on top of DO.
- systems/dynamic-workers — the per-request isolate sibling often paired with DO actors (Facets colocate DOs + Dynamic Workers on the same host).
- systems/durable-object-facets — the dynamic-binding counterpart to Durable Objects: per-tenant SQLite database spun up on demand with the platform as supervisor. Storage- layer sibling to Dynamic Workers (compute) and Dynamic Workflows (durable execution) in the 2026-05-01-canonicalised dynamic-binding pattern.
- concepts/actor-model — the programming-model primitive DOs realise.
- concepts/durable-execution — fibers make DO actors durable executors.
- one-to-one-agent-instance — the scaling premise making per-agent DOs economic.
- systems/cloudflare-artifacts — one DO per Git repo as the substrate of the 2026-04-16 versioned-storage primitive.
- systems/cloudflare-flagship — one DO per app as the control-plane source of truth + changelog for the 2026-04-17 feature-flag service.
- wasm-git-server — engine shape hosted inside the per-repo DO in Artifacts.
- repo-per-agent-session — per-session Artifacts repo on DO-backed storage.
- concepts/feature-flag — the primitive the Flagship per-app DO persists + audits.
- concepts/audit-trail — first-class co-location with the DO's single-writer config.
- do-backed-git-server — the full substrate pattern.
- do-plus-kv-edge-config-distribution — sibling pattern where the per-unit DO is paired with KV as the edge-local read tier (Flagship canonical instance).
Authorization is inherited from the Worker (2026-09-15)¶
Durable Objects have no roles or permissions of their own — access to a DO is determined entirely by your role on the Worker that implements it, under Cloudflare's resource-scoped authorization model. Two consequences (Source: sources/2026-09-15-cloudflare-workers-granular-authorization):
- Metadata Read-Only on the Worker exposes the DO's metrics, logs, and traces — but not the data stored inside the object.
- Because Durable Objects Data Studio can query and modify stored data directly, reading or changing that data requires the Editor role on the implementing Worker.
This is a clean example of collapsing a would-be separate permission surface into an existing one: the coordination/state primitive rides the compute primitive's authorization rather than introducing its own role matrix. See least-privileged access.