# celld vs Cloudflare Durable Objects: A Complete Technical Comparison

> Explore celld vs Cloudflare Durable Objects limitations. Discover celld a self-hosted alternative offering freedom from vendor lock-in but requiring infrastructure management.

- Repository: [Deno/celld](https://github.com/denoland/celld)
- Tags: comparison
- Published: 2026-08-15

---

**celld is a self-hosted alternative that replicates Cloudflare's Durable Objects programming model using per-object SQLite databases and S3-compatible storage, eliminating vendor lock-in while requiring you to manage your own infrastructure.**

Unlike Cloudflare's fully managed service, celld lets you run the same Workers runtime and Durable Object code on any machine you control. The denoland/celld repository provides a Rust-based daemon that embeds V8, executes Wrangler bundles, and handles state replication through a simple object-storage protocol.

## Deployment Model: Self-Hosted vs Managed Service

**Cloudflare Durable Objects** run exclusively on Cloudflare's edge network. You deploy code via Wrangler, and the platform handles scheduling, routing, and state persistence without exposing infrastructure details.

**celld** operates as a binary you install and run yourself. According to the project [README.md](https://github.com/denoland/celld/blob/main/README.md), each node embeds V8 and executes standard Wrangler bundles. You control the hardware, network topology, and upgrade cycle.

This fundamental difference shapes every other architectural decision in celld's design.

## State Storage Architecture

The storage model represents the most significant divergence between the two platforms.

| Platform | Storage Implementation |
|----------|------------------------|
| **celld** | Isolated **SQLite database per object**, replicated to S3-compatible bucket via compare-and-swap protocol |
| **Cloudflare** | Proprietary internal storage layer with transparent replication and durability |

In celld, every Durable Object receives its own SQLite file. The database file is replicated to an object store using the protocol defined in [[`crates/celld/protocol.rs`](https://github.com/denoland/celld/blob/main/crates/celld/protocol.rs)](https://github.com/denoland/celld/blob/main/crates/celld/protocol.rs). This design shards by construction—no single database can become a bottleneck regardless of object count.

Cloudflare's storage implementation remains opaque to developers. You write code against a consistent API while the platform manages geographic distribution, consistency, and recovery internally.

## Ownership and Coordination Mechanism

**celld** eliminates any central control plane. Nodes elect object owners exclusively through **object-storage compare-and-swap operations**. The S3-compatible bucket serves as the single source of truth for all coordination decisions. As documented in the README's "How it works" section, this means:

- No consensus algorithm like Raft or Paxos
- No separate join service for cluster membership
- Nodes can be added or removed by starting or stopping the binary

**Cloudflare** routes requests through its internal edge network, automatically directing traffic to the current owner. The platform runs proprietary lease and coordination mechanisms that developers never interact with directly.

## Scalability Characteristics

celld's **per-object SQLite** design provides natural horizontal sharding. Each object's state is completely isolated, so the system scales linearly with object count rather than hitting shared database limits.

Cloudflare abstracts sharding entirely. You program against a global namespace without considering data placement or partition boundaries.

The trade-off: celld requires you to design around object granularity, while Cloudflare hides these decisions but prevents inspection or optimization of the routing layer.

## Fault Tolerance and Replication

Replication in celld is **event-driven and lazy**. Changes write to SQLite locally, then replicate to the bucket. When a node fails, a new owner:

1. Reads the latest snapshot from the bucket
2. Replays any WAL segments
3. Assumes ownership via CAS operation

This model tolerates arbitrary node failures without configuration changes. The bucket's durability guarantees protect against data loss.

Cloudflare provides automatic fail-over across geographically distributed data centers with no operational input required. Recovery time and replication lag are unobservable platform internals.

## Execution Environment and Platform Features

The [[`docs/cloudflare-compat.md`](https://github.com/denoland/celld/blob/main/docs/cloudflare-compat.md)](https://github.com/denoland/celld/blob/main/docs/cloudflare-compat.md) file documents celld's intentionally narrow API surface. The runtime implements:

- `fetch` and RPC handlers
- Durable Object storage bindings
- Asset serving
- Basic Worker globals

**Not implemented**: KV, R2, D1, Cron triggers, AI bindings, and most Cloudflare-specific services. Your Durable Object code must limit itself to core runtime features or provide polyfills.

Cloudflare offers the complete platform stack. Applications can mix Durable Objects with object storage, relational databases, machine learning inference, and scheduled triggers within the same deployment.

## Network Security Model

Inter-node communication in celld uses plain HTTP with **HMAC-authenticated, clock-bounded requests** as implemented in [[`crates/celld/peer_auth.rs`](https://github.com/denoland/celld/blob/main/crates/celld/peer_auth.rs)](https://github.com/denoland/celld/blob/main/crates/celld/peer_auth.rs). You must:

- Expose peer ports on a private network, or
- Run an encrypted overlay like WireGuard

There is no built-in TLS termination or automatic certificate management. Security is your operational responsibility.

Cloudflare terminates TLS at the edge and routes traffic through its private backbone. Certificate management, DDoS protection, and geographic routing are automatic.

## Extensibility and Source Access

celld is fully open source under the MIT license. You can:

- Modify replication logic in [[`crates/celld/protocol.rs`](https://github.com/denoland/celld/blob/main/crates/celld/protocol.rs)](https://github.com/denoland/celld/blob/main/crates/celld/protocol.rs)
- Add custom storage backends beyond S3-compatible APIs
- Instrument the V8 runtime in [[`crates/celld/runtime.rs`](https://github.com/denoland/celld/blob/main/crates/celld/runtime.rs)](https://github.com/denoland/celld/blob/main/crates/celld/runtime.rs)
- Experiment with new bindings or RPC protocols

Cloudflare's platform is closed source. Extensions are limited to supported APIs and configuration options.

## Practical Code Example: Running a Counter on celld

The same Durable Object class runs on both platforms with no code changes:

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

```

Deploy to celld with:

```bash

# Build and upload bundle

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

# Start node

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

```

The client RPC remains identical to Cloudflare's API:

```js
const stub = COUNTER.idFromName("my-counter").getStub();
await stub.fetch("https://example.com/inc");

```

## When to Choose celld Over Cloudflare Durable Objects

**Select celld when you need:**

- Data residency on specific hardware or jurisdictions
- Network isolation from public cloud infrastructure
- Ability to audit or modify replication and coordination logic
- Predictable cost structure for high-throughput workloads
- Development or testing environments without Cloudflare accounts

**Select Cloudflare Durable Objects when you need:**

- Global edge deployment without infrastructure management
- Integration with KV, R2, D1, or other platform services
- Automatic geographic distribution and fail-over
- Built-in DDoS protection and TLS termination
- Minimal operational overhead

## Summary

- **celld** provides a **self-hosted, open-source** implementation of the Durable Objects programming model using per-object SQLite and S3-compatible storage.
- **Cloudflare DOs** offer a **fully managed, globally distributed** service with richer integrations but no infrastructure visibility.
- celld's **object-storage CAS coordination** eliminates the need for a control plane or consensus algorithm.
- The **narrow platform API** in celld means most Cloudflare-specific services are unavailable—plan for polyfills or service decomposition.
- Both systems execute identical **Worker and Durable Object code**, enabling portable applications with deployment flexibility.

## Frequently Asked Questions

### Can I run existing Cloudflare Workers on celld without modification?

**Most core Durable Object code runs unchanged**, but platform-specific APIs require attention. Review [[`docs/cloudflare-compat.md`](https://github.com/denoland/celld/blob/main/docs/cloudflare-compat.md)](https://github.com/denoland/celld/blob/main/docs/cloudflare-compat.md) against your dependencies. Code using KV, R2, D1, Cron, or AI bindings will need polyfills or architectural changes. The fetch handler, RPC surface, and Durable Object storage API are fully compatible.

### How does celld handle Durable Object consistency during fail-over?

**celld guarantees that only one node owns an object at any time** through compare-and-swap operations on the object store. When a node fails, the new owner reads the latest replicated SQLite snapshot before accepting requests. In-flight requests may fail, but state remains consistent. The replication lag depends on your bucket's latency and the volume of writes.

### What S3-compatible storage works with celld?

**Any provider implementing standard S3 APIs** should work, including AWS S3, MinIO, Backblaze B2, Wasabi, and Cloudflare R2 itself. The protocol in [[`crates/celld/protocol.rs`](https://github.com/denoland/celld/blob/main/crates/celld/protocol.rs)](https://github.com/denoland/celld/blob/main/crates/celld/protocol.rs) uses basic object operations: PUT with conditional headers, GET, and LIST. No multipart upload or complex lifecycle features are required.

### Does celld support horizontal scaling for single Durable Objects?

**No—single objects remain single-threaded**, identical to Cloudflare's model. A specific Durable Object ID executes on exactly one node at any time. However, **distinct objects shard automatically** across nodes without configuration. For CPU-intensive single objects, you must decompose the workload across multiple object IDs manually.