Why Ryan Dahl Defied His Promise and Built the celld JavaScript Runtime
After vowing never to create another JavaScript runtime, Ryan Dahl spent over a year developing celld, an open‑source, self‑hosted distributed runtime that brings Cloudflare Workers and Durable Objects to your own machines, using V8, SQLite, Rust async, and S3 for coordination, while exposing its performance trade‑offs and early‑stage limitations.
Ryan Dahl once promised himself he would never write another JavaScript runtime, yet after more than a year of intermittent work he released celld, an open‑source, self‑hosted distributed runtime that aims to bring Cloudflare Workers and Durable Objects onto developers' own machines.
A “cell” is a tiny server with SQLite
Stateful services such as chat rooms, collaborative documents, game lobbies, user sessions, and AI agents need to retain state across requests and handle concurrent updates. Traditional solutions rely on stateless services backed by a shared database, pushing concurrency control, hot‑spot handling, connection management, and failure recovery onto the database and surrounding infrastructure.
celld adopts the Durable Objects model: each cell represents a user, document, chat room, or AI agent, and owns its own JavaScript execution environment and private SQLite database. Only one writer can access a cell at a time, so requests execute on a single thread, eliminating many distributed lock and database contention issues at the programming‑model level.
The official repository provides a tiny counter example (only a few dozen lines). The worker looks up a cell by name (e.g., room-42) and forwards the request to the corresponding Durable Object:
export class Counter {
constructor(state, env) { this.state = state; }
async fetch(request) {
let n = (await this.state.storage.get("n")) ?? 0;
n++;
await this.state.storage.put("n", n);
return new Response(JSON.stringify({ n, url: request.url }));
}
}
export default {
async fetch(request, env) {
const id = env.COUNTER.idFromName("room-42");
return env.COUNTER.get(id).fetch(request);
}
};If you have used Cloudflare Workers and Durable Objects, the API feels familiar. celld accepts Wrangler projects and supports module Workers, Durable Object bindings, static assets, WebSocket, alarms, and most JavaScript RPCs.
The interesting part: using S3 as a coordination hub
Each host embeds V8 to run JavaScript; each cell stores state in SQLite; LTX records incremental SQLite changes; Tokio handles asynchronous I/O. The entire cluster shares a single S3‑compatible object store, which holds not only data but also deployment artifacts, cell state, ownership records, host leases, and inter‑host authentication information.
When a request lands on a cell, the host uses an atomic compare‑and‑swap operation on the object store to claim ownership, ensuring that a cell is owned by only one host at any time. If a host crashes or a cell is awakened, a new host restores the SQLite data from the bucket and resumes processing.
There is no separate control plane or consensus service; any new machine pointing at the same bucket can join the cluster.
Cost trade‑off: each durable write must wait for at least one round‑trip to the object store. celld confirms a write only after the data reaches the bucket, targeting an RPO of 0 so that confirmed writes survive host failures.
This design favors data safety and operational simplicity over ultra‑low write latency; the tail latency of object storage, rate‑limiting, and network conditions become part of the write path.
Near‑zero cost after sleep, scales better with size
Durable Objects allow massive numbers of fine‑grained objects without keeping them all in memory. celld also evicts idle cells from memory; cells without a host exist solely as data in the object store, and cells with a dormant WebSocket can retain the connection until the next event.
The official estimate: an 8 GB machine can host about 1 000 resident cells, each costing roughly $0.05 per month. Sleeping cells mainly incur object‑store costs.
These numbers depend on hardware price, object‑store request fees, cross‑region traffic, working‑set size, and write frequency, so they are not universal cost‑saving guarantees. The advantage is the ability to let low‑activity objects sleep while keeping hot resources for active work.
In a recent test, ten 4‑vCPU, 8 GB machines handled 10 000 resident cells and 20 000 concurrent WebSocket connections. Stopping two machines allowed all cell data to become available again within about 11 seconds, assuming sufficient spare capacity.
Measured latency for resident cells: p50 ≈ 1.1 ms, p99 ≈ 7 ms for local requests (which bypass the object store). Cold starts and durable writes still need to touch the bucket.
Don’t rush to production yet
celld’s architecture is elegant, but the project is still in alpha.
It implements only a subset of Workers and Durable Objects capabilities; features such as KV, R2, Workers AI, Vectorize, scheduled triggers, custom domains, and TLS termination are missing, and the Node.js API is only partially covered.
A cluster currently runs a single application; there is no multi‑tenant scheduler or global placement layer.
Host‑to‑host protocol includes authentication but not TLS encryption, requiring deployment in a trusted private network.
Bucket credentials act as cluster‑admin privileges; leakage compromises more than just data.
Windows is not supported yet; Intel Macs lack pre‑compiled binaries.
Automatic updates, hosted entry points, and mature pressure‑scheduling strategies are not yet implemented.
Nevertheless, Dahl’s team has invested heavily in reliability testing. They run identical programs on workerd and celld, compare outputs, and use deterministic simulation to inject lease contention, clock drift, host crashes, and object‑store latency. In live tests they kill host processes, delete local databases, and verify that confirmed writes survive.
While this does not replace long‑term production validation, it shows the team understands that the most dangerous moments are not whether a demo runs, but whether the system can keep its promises when the worst‑case failure occurs.
Redefining the boundary
Node.js made server‑side JavaScript mainstream; Deno attempted to redo the JavaScript toolchain. celld seeks to shift the boundary between application code and cloud platforms.
The most noteworthy aspect for developers is not that it is “another JS runtime,” but that a mature stateful programming model can be packaged as an open‑source program you run on your own hardware. Code still targets Workers and Durable Objects, data lives in a bucket you control, and computation runs on your servers.
If celld gradually adds compatibility, scheduling, security, and operational tooling, it could become a competitive piece of infrastructure for self‑hosted real‑time apps, collaborative services, and AI agents.
It is still too early to hand over core production systems, but the direction is certainly worth front‑end and Node.js developers’ attention.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
