Cloudflare · Durable Objects · 2026

How Cloudflare Durable Objects work.

Follow one tap on a shared counter into a Durable Object: one name, one thread, one SQLite log shipped to object storage — a recipe that now runs on S3.

AUG 2026 ~10 MIN 7 SCENES

01The bug we are going to fix

Cloudflare launched Durable Objects in 2020 with a modest example: an atomic counter. Not a database with a counter table — a single object, addressed by name, that can be incremented from anywhere on Earth without ever losing a tap.

That example is the whole product in miniature, so this page starts where the example starts: with the tap that gets lost. Everything below is the published mechanism — from Cloudflare's own engineering posts, and from celld, a new open-source implementation of the same model.

A shared counter looks trivial: read the value, add one, write it back. Alice and Bob tap at the same instant — two requests, one server.

The handler is async. Each request pauses at every await. While one pauses, the other runs. Both read the same 5 before either writes.

Both write 6. The counter says 6, two taps arrived, one tap vanished — silently. This is the bug Durable Objects were built to fix.

02Two ways to hold state

The default architecture keeps application servers stateless and moves all truth into one shared database. Locks and transactions serialize access there — every tap pays a round trip, and the coordinator is one machine with one blast radius.

The other shape decides at the door. A Durable Object is a small server with a globally unique name and its own private storage. One object per room, document, or agent — and coordination becomes a local variable.

It's the actor model, the same idea as Erlang's processes at WhatsApp. Actors give you order; they do not give you durability. For that, this story borrows two earlier notes: the write-ahead log and the storage cloud.

ONE SHARED DATABASE ONE OBJECT PER NAME LOCK serialized · one blast radius each with its own storage

idFromName("room-7") resolves, from anywhere on Earth, to exactly one running instance. Not usually one — one. Every request carrying that name lands on the same object.

Inside, requests queue into a single event loop; two requests never run at the same instant. Yet the race from Act 01 can still happen here — every await is a door the next request walks through.

So the platform moved the doors. Input gates hold new events while storage is in flight. With SQLite in the same thread, queries are synchronous. The race is structurally gone.

Your "+1, OK" waits at the output gate until the write is confirmed durable. If confirmation fails, the reply is discarded and the object restarts — a false OK can never escape.

The counter never learned about locks.
It just always had exactly one clerk.

Every commit appends a frame to the object's SQLite write-ahead log — the WAL move, but per object. Cloudflare's storage layer hooks SQLite itself and intercepts each frame as it lands.

Each frame immediately races to five followers, one machine per physical building. Three acknowledgements confirm the write — and the output gate from Act 02 opens.

Frames roll up to object storage in batches of up to 10 seconds or 16 MB. Whenever the log since the last snapshot outgrows the database itself, a full snapshot ships. Recovery never replays more than twice the database.

The machine dies. The system asks three of five followers to stop vouching for it — that's the whole fence. A replacement restores and replays. No election runs — there was only ever one writer.

Records are kept 30 days past their snapshot, so any object can roll back to any moment in the last month. Point-in-time recovery was not designed; it fell out of keeping the records.

In August 2026, Deno Land published celld: an Apache-2.0 daemon that runs your Workers and Durable Objects code unchanged on your own machines — V8, one SQLite database per cell, persistence that "rests entirely on S3."

Ownership of a cell is a record in the bucket, claimed by one atomic conditional write. No membership protocol, no failure detector, no consensus. Stores without conditional writes cannot fence.

Every activation bumps an epoch, and replication writes under e<epoch>/ prefixes. A partitioned ex-owner keeps writing into a dead prefix no restore will ever read. Nodes hold 10-second leases and fence themselves when they cannot renew.

celld calls itself a love letter to the model Kenton Varda's team designed. Meanwhile Cloudflare itself builds Queues, Workflows and D1 on Durable Objects. Good primitives escape their vendors.

Every cell starts inactive: a few objects in a bucket — the ownership record, the LTX segments, a snapshot. No process, no memory, no rent. A fleet of a million idle agents costs a fleet of empty drawers.

A request arrives at any node. The node claims the ownership record with one conditional write, advances the epoch, restores the SQLite database, and the constructor runs. On a 2-vCPU fleet node, celld measures that cold activation at a p50 of 35.9 ms.

While it works, the cell is resident — 0.47 MB of RAM, measured. Idle with live WebSocket clients, it hibernates: memory goes, the sockets stay, and waking it back is measured at ~4 ms.

Evicted, handed over, or fenced, the cell returns to the bucket. Nodes find each other only through leases in that bucket — no join command, no member list. The nodes are interchangeable; the bucket is the database.

ACT 06 · THE RECEIPTS

Measured, attributed, stamped

Believe measurements, not adjectives. The celld figures are its own published numbers — kill tests with SIGKILL under load. Every plate carries its stamp.

0 ACKNOWLEDGED WRITES LOST — KILL TESTS, LOADED NODE CELLD MEASURED
~90 MS DURABLE WRITE LATENCY, REGION-LOCAL BUCKET CELLD MEASURED
~20 S FAILOVER AFTER NODE LOSS — ZERO LOST CELLD MEASURED
0.47 MB RAM PER RESIDENT CELL CELLD MEASURED
2,500 RESIDENT CELLS PER 8 GB NODE CELLD MEASURED
~$0.02 PER RESIDENT CELL-MONTH — CELLD'S COST MODEL CELLD MODELED
10 GB SQLITE STORAGE PER OBJECT, GA CLOUDFLARE · 2025-04-07

ALSO ON RECORD: ONE WRITER PER CELL (EPOCH-FENCED) · WRITERS 1 · ISOLATE HEAP 128 MB PER OBJECT — CELLD MATCHES CLOUDFLARE'S LIMIT · SPEED FIGURES: ONE NODE, TRIVIAL CELLS, APPLE M-SERIES LAPTOP OVER LOOPBACK, AS LABELED BY CELLD.

03One order, copies, no election

A durable object is the write-ahead log and the storage cloud, merged into one small machine. The name picks the machine. The single thread makes order free — no locks, because there is nothing to race against. The log and its copies make each write survive the machine.

Consensus protocols exist to agree when there could be several writers. Pin the writer to the name and the election never happens. What remains is a record, copies of it in independent places, and a fence for zombies — and that is durable enough to run a counter, a chat room, a database, or a whole open-source stack on top of a bucket.

If you followed the two earlier notes — how a write-ahead log saves a $100 transfer and how S3 earns its eleven nines — you had already read both halves of this machine.

DATERECORDSOURCE
2020Durable Objects announced — named, single-instance, stateful serverlessCF BLOG
2021Input gates, output gates, automatic cachingCF BLOG
2024SQLite in the same thread; SRS — WAL frames, 5 followers, 3 acks, batches, snapshots, PITRCF BLOG
2025SQLite storage generally available — 10 GB per objectCF CHANGELOG
2026celld — self-hosted Durable Objects on V8 + SQLite + LTX + S3 (Apache-2.0)DENO LAND
MECHANISM SOURCES: "WORKERS DURABLE OBJECTS BETA" (2020), "DURABLE OBJECTS: EASY, FAST, CORRECT — CHOOSE THREE" (2021-08-03), "ZERO-LATENCY SQLITE STORAGE IN EVERY DURABLE OBJECT" (2024-09), GA CHANGELOG (2025-04-07), ALL BY CLOUDFLARE; CELLD.DEV DOCS INCLUDING FENCING AND TESTING PAGES, AND GITHUB.COM/DENOLAND/CELLD (AUGUST 2026). LTX IS LITESTREAM'S REPLICA FORMAT, BY BEN JOHNSON — CLOUDFLARE CREDITS THE SAME ANCESTOR IDEA.