>_ DevTrendsen

Language

Home

Languages

Sections

Frontend Backend Mobile DevOps AI / ML GameDev Blockchain Embedded Security
Rust

How to Run Cloudflare Durable Objects on Your Own Servers Using celld

Ryan Dahl and the Deno team quietly open-sourced the celld project. If you've ever envied Cloudflare users for their Durable Objects concept but didn't want to deal with vendor lock-in, this might interest you.

celld is a Rust daemon runtime that can run Cloudflare Workers bundles and isolated Durable Objects instances on your own hardware. No Etcd, no Raft, and no heavyweight coordination services.

The Core of the Concept

Traditional backends are typically split into stateless microservices and a single large relational database. As load increases, the database inevitably becomes the main bottleneck.

Cloudflare proposed a different approach. Each active application entity (for example, a chat room, shopping cart, or document session) gets its own V8 isolate and a personal SQLite database. The object wakes up when a request arrives, holds state in memory and a local SQLite file, and simply goes to sleep when idle.

The main problem was the closed nature of the ecosystem: running such a setup outside of Cloudflare's infrastructure was practically impossible until now.

How celld Works Internally

The celld developers went for radical simplification. The node architecture consists of four components:

  1. Embedded V8 for executing JavaScript and TypeScript code from Wrangler bundles.
  2. Local SQLite for each object's separate database file.
  3. S3-compatible storage (AWS S3, MinIO, Cloudflare R2) as the single source of truth.
  4. Inter-server transport with HMAC signing for data exchange between nodes.

The most interesting solution here is the abandonment of classical consensus protocols. Cluster nodes don't need to elect a leader or run Consul.

Instead, servers communicate with S3 through an atomic Compare-And-Swap (CAS) operation. When a node wants to take ownership of an object, it writes an ownership file to the S3 bucket. Whoever manages to update the record via CAS first handles the traffic. If a node crashes, the write timeout expires, and a neighboring server picks up the object, downloads its fresh SQLite database from the bucket, and continues working.

Launch and Deployment

Standard Wrangler builds work for building the project, but you'll need a server with 5 and the binary itself 6.

Installation is done with a single command:

0

The workflow is split into two steps. First, upload the worker build to the bucket:

1

Then start the daemon on the server:

2

Each node in the cluster reads the manifest 7 from the bucket. If you need to spin up an additional server, you launch another process with the same bucket and specify its network address in 8.

Regarding security: celld's inter-server traffic doesn't encrypt TLS out of the box. The authors recommend placing internal node ports behind a secure overlay network like WireGuard or Tailscale. All peer requests are automatically signed with an HMAC key 9 that the first node creates automatically in the bucket.

Diagnostics and Load Management

For cluster monitoring, there's the 10 utility. It polls neighbors and displays current metrics:

3

The command will output CPU consumption, RSS memory, the number of active WebSocket connections, and the count of live objects on each node.

If a server starts getting overloaded, celld has a pressure shedding mechanism for active objects. Limits are set via environment variables:

4

When the threshold is exceeded, celld saves inactive objects to S3, releases ownership, and stops accepting new entities until the load drops to the value of 11. Objects with frequent requests or open WebSocket connections are not affected.

An Unusual Approach to Contributing

If you go to the 12 repository intending to open a Pull Request, you'll find the button disabled. Forks are allowed, but PRs on GitHub are completely disabled.

Ryan Dahl explains this as a fight against spam from AI agents: reviewing giant auto-generated pull requests without context takes too much time from maintainers. Those who want to send a patch are asked to make 13 and email the file to the personal address 14.

Who Should Take a Look at This Project

The project is in active development, with protocol specifications stored directly in the Rust crate code 15. It's too early to pull it into critical production, but experimenting is definitely worth it.

The tool will be useful in the following cases:

  1. Developers of multiplayer services, chats, and custom CRMs.
  2. Teams planning to move away from Cloudflare lock-in without rewriting code.
  3. Fans of the architecture with a separate database per client-user.
  4. Engineers learning about distributed systems without Raft and Etcd.

Related projects