In celld, a cell is a Durable Object — a named, stateful unit with a private SQLite database. Cells use the exact same JavaScript API as Cloudflare Durable Objects. You make one cell for each user, each document, each chat room, or each AI agent. A cell serves HTTP, holds WebSocket connections, sets alarms, and makes outbound connections.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/denoland/celld/llms.txt
Use this file to discover all available pages before exploring further.
Every acknowledged write is proven durable before the response returns
(RPO=0). The loss of a node cannot lose an acknowledged write.
Defining a Durable Object
A Durable Object class exports a constructor that receivesstate and env, and a fetch method that handles incoming requests. Here is the complete counter example:
wrangler.jsonc for this project declares the binding and migration:
Storage API
state.storage is backed by a private per-cell SQLite database. All storage operations are synchronous with respect to request handling — they do not interleave with other operations on the same cell.
| Method | Description |
|---|---|
get(key) | Read a value by key. Returns undefined if the key does not exist. |
put(key, value) | Write a value. The write is durable before the call resolves. |
delete(key) | Delete a key. |
list(options?) | List key-value pairs, with optional prefix, start, end, limit, and reverse. |
deleteAll() | Delete all keys. |
getAlarm() | Return the scheduled alarm time in milliseconds, or null. |
setAlarm(scheduledTime) | Schedule an alarm at a Unix timestamp in milliseconds. |
deleteAlarm() | Cancel the pending alarm. |
transaction(fn) | Run a callback inside an atomic transaction. |
sql | Access the underlying SQLite engine directly for SQL queries. |
Single-writer guarantee
Each cell runs on one thread. Two requests to the same cell never run simultaneously. A second request can interleave only while the firstawaits an asynchronous operation — and because storage operations are synchronous, they never interleave at all. The data in a cell therefore stays consistent without locks.
Cell lifecycle
A cell moves through four states:Idle
The cell is in memory but waiting. Celld removes an idle cell from memory
after a short period.
Hibernated
The cell has been removed from memory but retains its hibernatable
WebSocket clients and stays on its node. The constructor runs again on the
next event — only the WebSocket connections and the node assignment
distinguish hibernation from the inactive state.
Migrations
Celld usesdurable_objects.migrations in wrangler.jsonc to track which classes have SQLite storage. Use new_sqlite_classes to mark a class as SQLite-backed on its first deployment:
Bindings
The Worker accesses a Durable Object namespace throughenv. Use idFromName to derive a deterministic ID from a string key, get to obtain a stub, and fetch to send a request:
idFromName is deterministic: the same name always maps to the same cell, across nodes and across restarts. Route by user ID, room name, document ID, or any other natural key.
Alarms
A cell can schedule analarm that fires at a specific time. Use setAlarm to arm it and implement an alarm method on the class to handle it:
info.retryCount so the handler can distinguish retries from first fires.