Architectural Differences Between celld and Cloudflare Durable Objects: A Technical Deep Dive

celld is a self-hosted daemon that replicates Cloudflare's Durable Objects programming model using per-object SQLite databases and S3-compatible object storage for coordination, whereas Cloudflare Durable Objects run as a fully managed service on Cloudflare's edge network with proprietary storage and coordination mechanisms.

The denoland/celld repository provides an open-source implementation of the Cloudflare Workers runtime and Durable Objects (DO) model designed for self-hosted deployment. While both platforms expose the same developer-facing API for stateful serverless computing, they differ fundamentally in storage architecture, coordination mechanisms, and operational control. Understanding these architectural differences between celld and Cloudflare Durable Objects is essential for teams deciding between managed convenience and infrastructure sovereignty.

Deployment and Ownership Models

Self-Hosted Binary vs. Managed Edge Service

celld operates as a binary you install locally or inside a container. Each node embeds V8 and executes Wrangler bundles directly on your hardware, giving you complete control over the runtime environment. You manage the binary lifecycle, hardware or VM provisioning, and network configuration.

In contrast, Cloudflare Durable Objects run exclusively on Cloudflare's edge network as a managed service. You deploy code to Cloudflare's infrastructure without hosting the runtime yourself, sacrificing control for operational simplicity.

State Storage Architecture

SQLite-Per-Object vs. Proprietary Storage

The most significant architectural divergence lies in persistence implementation. In celld, every Durable Object is backed by an isolated SQLite database stored as a single file per object. This design is implemented in the core runtime and ensures that state is physically separated by object identity.

Cloudflare Durable Objects store state in Cloudflare's internal proprietary storage layer. The replication, durability, and failover mechanisms are handled transparently by the platform without exposing storage implementation details to developers.

Replication via Object Storage CAS

celld replicates state to an S3-compatible bucket (or any object store) using a simple compare-and-swap protocol defined in crates/celld/protocol.rs. Every change is written to the bucket, and ownership transitions rely on this object storage layer as the single source of truth.

Cloudflare's native implementation manages replication internally using their global edge network infrastructure, requiring no configuration or visibility into the replication protocol from users.

Coordination and Consensus

Decentralized Ownership Election

celld implements a decentralized coordination model with no central control plane or consensus algorithm. Nodes elect an owner for each object exclusively via object-storage CAS operations. When a node wants to own an object, it attempts to write a lease to the bucket; if successful, it becomes the exclusive handler for that object's requests.

Cloudflare automatically routes requests to the current owner through their internal edge network, running proprietary coordination and lease mechanisms invisible to developers.

Scalability Characteristics

Natural Sharding by Construction

Because each object in celld lives in its own SQLite file, the system shards by construction. There is no single shared database that can become a bottleneck, allowing horizontal scalability across nodes simply by distributing objects.

Cloudflare handles sharding internally and invisibly. Developers write code as if accessing a single global state, while the platform manages the physical distribution of objects across their edge infrastructure.

Execution Environment and Compatibility

V8 Isolate Runtime Limitations

celld executes Workers code in a V8 isolate that processes Wrangler bundles, but the runtime includes only the core Worker surface—fetch, RPC, assets, and DO bindings. According to docs/cloudflare-compat.md, features such as KV, R2, Cron, and platform-specific services are not implemented.

Cloudflare Durable Objects provide access to the full Cloudflare platform stack, including KV, R2, D1, Cron triggers, AI services, and other proprietary bindings.

Network Topology and Security

Peer-to-Peer HTTP with HMAC Authentication

Communication between celld nodes occurs over plain HTTP with HMAC-authenticated, clock-bounded requests implemented in crates/celld/peer_auth.rs. You must expose peer ports on a private network or encrypted overlay (such as WireGuard) to secure inter-node traffic.

Cloudflare routes traffic through their internal edge network, handling TLS termination, DDoS protection, and geographic routing automatically without requiring network configuration from developers.

Practical Implementation Examples

Defining a Durable Object in celld

The following code works identically on both platforms, but celld stores the state in SQLite and replicates it via the configured bucket:

export class Counter {
  async fetch(request, env) {
    const url = new URL(request.url);
    if (url.pathname === "/inc") {
      await env.storage.put("value", (await env.storage.get("value")) + 1);
      return new Response("incremented");
    }
    const value = await env.storage.get("value");
    return new Response(`value = ${value}`);
  }
}

// wrangler.jsonc configuration
{
  "durable_objects": {
    "bindings": [{ "name": "COUNTER", "class_name": "Counter" }]
  }
}

Deploying and Running celld Nodes

Deploy your worker bundle and start nodes using the CLI as described in the project's README.md:


# Deploy the worker bundle to the bucket

celld deploy . --bucket s3://my-cells-bucket

# Start a node (repeat on multiple machines)

celld --bucket s3://my-cells-bucket \
      --listen 0.0.0.0:8080 \
      --advertise node-a.internal:8080

Accessing Objects from Clients

The RPC surface remains compatible with Cloudflare's API, with celld's runtime handling the underlying transport:

const stub = COUNTER.idFromName("my-counter").getStub();
await stub.fetch("https://example.com/inc");
const resp = await stub.fetch("https://example.com/");
console.log(await resp.text()); // "value = 42"

Summary

  • celld provides a self-hosted alternative to Cloudflare Durable Objects using per-object SQLite files and S3-compatible storage for state management.
  • State replication relies on a compare-and-swap protocol (crates/celld/protocol.rs) rather than proprietary infrastructure.
  • No central control plane exists in celld; coordination happens through object-storage operations, unlike Cloudflare's managed routing.
  • Each object maintains isolated SQLite storage, creating natural sharding without shared database bottlenecks.
  • The runtime supports core Durable Object APIs but lacks Cloudflare-specific services like KV, R2, and Cron according to docs/cloudflare-compat.md.
  • Nodes communicate via HMAC-authenticated HTTP (crates/celld/peer_auth.rs) requiring manual network security configuration.

Frequently Asked Questions

Can I migrate existing Cloudflare Durable Objects code to celld without modifications?

Yes, celld implements the same JavaScript API surface for Durable Objects, including fetch handlers and env.storage methods. However, you must remove or polyfill dependencies on Cloudflare-specific services like KV, R2, or D1 that are not implemented in the open-source runtime. Review the compatibility matrix in docs/cloudflare-compat.md before migrating production workloads.

How does celld handle failover if a node crashes?

celld uses an event-driven replication model where every state change is written to the configured S3-compatible bucket. When a node crashes, another node can take over ownership by reading the latest SQLite snapshot from the bucket and acquiring a new lease via the CAS protocol. This design eliminates the need for a separate join service or complex consensus algorithms.

What are the security implications of running celld on my own infrastructure?

You are responsible for securing the peer-to-peer communication layer between nodes. The implementation in crates/celld/peer_auth.rs provides HMAC authentication and clock-bounded request validation, but you must expose peer ports on private networks or encrypted overlays like WireGuard. Unlike Cloudflare's managed service, TLS termination and DDoS protection are not handled automatically and require manual configuration.

Does celld support horizontal scaling across multiple regions?

Yes, because each Durable Object is an independent SQLite file replicated to object storage, you can run celld nodes in multiple geographic regions. Objects automatically migrate to whichever node requests ownership, limited only by the latency of your object storage backend. This architecture avoids the single-database bottleneck that limits traditional stateful systems.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →