Hey everyone, Alex here. Welcome back to "Coding with Alex" at sysseder.com! If you’ve spent any time building modern web applications, you’ve probably run into the classic state dilemma of serverless architectures. We love the scale, the low latency, and the "pay-for-what-you-use" model of edge computing. But the moment you need real-time, highly coordinated, stateful features—like a collaborative document editor, a live chat room, or a multiplayer game lobby—the stateless serverless dream starts to crack.
For a while now, Cloudflare’s Durable Objects have been the gold standard for solving this. They give you a way to run stateful code at the edge with strong consistency guarantees, tied to a single, globally accessible coordinator. But there's a catch: you are locked into Cloudflare’s proprietary infrastructure. What if you want to deploy to your own Kubernetes cluster, run it on-premise, or test it entirely offline on your local machine?
This is why Celld (which just hit the top of Hacker News) is such a massive deal. Celld is an open-source, self-hosted, distributed Durable Objects runtime. Today, we’re going to dive deep into what Celld is, how its architecture works, and how you can use it to build stateful, real-time applications without the vendor lock-in. Let's get into it!
The State Problem in Serverless
Before we look at Celld, let’s quickly recap why state at the edge is so hard. Traditional databases (like Postgres or MySQL) are centralized. When you spin up hundreds of stateless edge functions (like AWS Lambda or Vercel Functions) across the globe, they all have to query that single central database. This introduces massive latency bottlenecking and database connection exhaustion.
To solve this, we often use WebSockets and in-memory stores like Redis. But managing WebSocket connections, pub/sub synchronization, and race conditions across distributed nodes is incredibly complex.
This is where the Durable Object pattern shines. Instead of separation of compute and state, a Durable Object merges them. It is a micro-actor: a single, unique instance of a class that runs in memory, processes messages sequentially (avoiding race conditions), and has its own persistent, low-latency storage. If another node wants to talk to that specific object, the platform automatically routes the request to the exact machine where that object is running.
Enter Celld: Decentralized and Self-Hosted
Celld brings this powerful actor-based model to the open-source world. Written in Rust for maximum performance and memory safety, Celld allows you to run distributed Durable Objects on your own infrastructure. Whether you are running on bare-metal servers, a Raspberry Pi cluster, or AWS EC2, Celld coordinates the state routing and persistence for you.
Key Architectural Pillars of Celld
- Actor-based Model: Each object is a lightweight actor with a unique ID, running isolated JavaScript/TypeScript code.
- Raft Consensus & Clustering: Celld nodes form a cluster using the Raft consensus algorithm to handle node membership, health checks, and global routing tables.
- Automated Routing: You don't need to know where an object is running. You send a request to any node in the Celld cluster with the object's ID, and Celld automatically routes the request to the node hosting that object.
- Local Storage Engine: Each node uses an embedded transactional key-value store (typically RocksDB or SQLite under the hood) to persist the object's state locally.
Under the Hood: How Celld Routes Traffic
To understand why this is so powerful, let's look at how a request flows through a Celld cluster when a user interacts with a collaborative document, say, Document #doc-99.
[User Client]
│ (HTTPS / WebSockets)
▼
[Celld Node A] (Ingress Node)
│
├─► Is "doc-99" running here?
│ No. Check cluster routing table...
│ "doc-99" is currently active on Node C.
│
▼ (Internal Cluster RPC)
[Celld Node C] (Host Node)
│ ──► Executes JavaScript Worker for "doc-99"
│ ──► Reads/Writes to local transactional storage
▼
[Success Response] ──► Routed back via Node A ──► [User Client]
Because Celld handles this routing layer internally via high-speed gRPC/TCP, your application logic remains incredibly simple. You write code as if you are talking to a local object, and Celld handles the distributed system complexity.
Getting Started: Writing Your First Celld Object
Let's build a practical example: a real-time collaborative counter. Imagine multiple users on a web app clicking a button, and we need the count to be perfectly synchronized, globally, with zero race conditions.
First, we define our Durable Object in TypeScript. The object class exposes methods to interact with its state, and Celld ensures that only one request is processed at a time for this specific object ID.
// counter-object.ts
export class CounterObject {
private state: CelldState;
constructor(state: CelldState) {
this.state = state;
}
// Handle incoming HTTP requests routed to this object
async fetch(request: Request): Promise {
const url = new URL(request.url);
// Get current value from persistent local storage
let value: number = (await this.state.storage.get("value")) || 0;
if (url.pathname === "/increment") {
value++;
// Persist the new state
await this.state.storage.put("value", value);
return new Response(JSON.stringify({ count: value }), {
headers: { "Content-Type": "application/json" },
});
}
if (url.pathname === "/get") {
return new Response(JSON.stringify({ count: value }), {
headers: { "Content-Type": "application/json" },
});
}
return new Response("Not Found", { status: 404 });
}
}
Deploying to a Celld Node
To run this, we spin up a Celld instance. Celld exposes an admin API and a data gateway. We register our compiled JavaScript file with the Celld daemon:
# Register our WebAssembly/JS worker with the Celld cluster
celld-cli deploy --name counter-worker --file ./dist/counter-object.js
# Bind a namespace to our worker class
celld-cli namespace create counters --worker counter-worker
Now, our cluster is ready to route requests! We can interact with our durable counter from any HTTP client by passing a unique object ID in the headers or URL path. Celld uses this ID to locate or initialize the object on the cluster.
# Increment the counter for "project-alpha"
curl -X POST https://your-celld-cluster.com/ns/counters/id/project-alpha/increment
# Output: {"count": 1}
# Increment again - routing guarantees it hits the exact same in-memory object instance
curl -X POST https://your-celld-cluster.com/ns/counters/id/project-alpha/increment
# Output: {"count": 2}
Why Celld is a Game-Changer for DevOps and Platform Engineers
If you're running infrastructure, the benefits of Celld go far beyond just escaping Cloudflare's pricing tiers. It opens up architecture designs that were previously incredibly difficult to self-host:
1. Low Latency Data Locality
Because Celld runs on your own VMs, you can deploy clusters in regional data centers close to your physical databases or your users. If you have strict GDPR requirements where user data cannot leave a specific country, Celld allows you to pin specific Durable Object IDs to nodes residing in specific geographic regions.
2. Seamless Offline Development
One of the biggest pain points of building for proprietary edge platforms is local development. Emulators are often slow, buggy, or don't perfectly match production behavior. With Celld, because it's a lightweight Rust binary, you can run the exact same cluster architecture on your local laptop using Docker Compose as you do in production Kubernetes.
3. Hybrid Cloud Strategies
With Celld, you can bridge the gap between public clouds and on-premise infrastructure. You can have Celld nodes running in AWS for bursting capacity, while keeping master nodes in your private data center for data sovereignty.
Conclusion: The Future is Open-Source Edge
The release of Celld marks a major milestone in the democratization of edge computing. For years, developers have been forced to choose between the ease of use of proprietary serverless features and the freedom of self-hosted containerized workloads. Celld proves that you can have both: the elegant, highly concurrent actor model of Durable Objects, combined with the absolute control of open-source software.
If you are planning your next real-time collaborative tool, distributed IoT coordinator, or multiplayer gaming backend, I highly recommend checking out Celld.
What are your thoughts? Are you ready to move away from proprietary edge runtimes, or is the convenience of managed services still too good to pass up? Let me know in the comments below, or hit me up on Twitter/X at @sysseder!
Until next time, happy coding!