Release v0.2.0 · denoland/celld · GitHub
//releases/show" data-turbo-transient="true" />
Skip to content
Type / to search
Sign in<br>Sign upAppearance settings
You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.
Dismiss alert
{{ message }}
Uh oh!
There was an error while loading. Please reload this page.
denoland
celld
Public
Notifications<br>You must be signed in to change notification settings
Fork<br>105
Star<br>3.3k
v0.2.0
Latest
Latest
Compare
Choose a tag to compare
Sorry, something went wrong.
Filter
Loading
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
No results found
View all tags
github-actions
released this
12 Aug 22:54
Immutable<br>release. Only release title and notes can be modified.
v0.2.0
3f22aed
This commit was signed with the committer’s verified signature .
ry<br>Ryan Dahl
SSH Key Fingerprint: FLWRNu9UKHII2u4eW2TJh0Ck2NMfAg5j16Oq3SXv7ks<br>Verified
Learn about vigilant mode.
celld v0.2.0 changes three foundations: how cells share memory, how their state replicates, and how a fleet stays available when its object store fails or slows.
Isolates and memory:
Resident cells share isolates and run turn by turn on a shared pool. v0.1.0 held one OS thread and one isolate for each cell.
A resident cell costs ~471 KB against ~3.4 MB in v0.1.0, measured linear to 2,500 resident cells (~1.2 GB) on one node. Memory no longer limits the resident population; admission and RSS shedding set the limit.
A handler that awaits I/O releases its isolate between turns, so co-resident cells cannot stall each other.
celld reclaims empty cell heaps and reuses retired isolate slots, so a long-lived node cannot leak isolates.
jemalloc is the global allocator.
Two listeners:
celld now separates the data plane from the control plane. The public listener (--listen) serves only your Worker's routes and /__celld/health. A new internal listener (--internal-listen) carries everything else: the operator API (/state, /shutdown) and all node-to-node peer traffic. Keep the internal port on a private network.
A public listener on a non-loopback address requires an explicit internal listener. --advertise names the internal address, and celld diagnose probes peers at that address.
Replication and compaction:
celld compacts many small level-0 replication objects into additive level-1 blocks (LTX v0.5.2 block format). Compaction is on by default and never deletes a source object.
A takeover of a write-heavy cell reads tens of objects instead of thousands. In one measured case, a cell with 4,096 durable writes restored from 42 objects and 0.6 MB instead of 4,116 objects and 19 MB, 3.8 times faster.
A restore downloads the objects in its plan concurrently, under one ceiling for the whole node.
A takeover pins the exact point in the replicated history that it restored from. celld never restores data that a fenced former owner uploads after that point, so a cell's history cannot fork and a failed write cannot reappear after a failover.
Compaction runs off the request path with a bounded duty cycle. A node that restarts with a large uncompacted backlog drains it without blocking durable writes.
celld and Litestream v0.5.16 can read both block and frame files. Litestream v0.5.11 can read only frame files.
Availability under storage faults:
The time that remains on the last renewed lease bounds each lease renewal attempt, so one hung conditional write can no longer use the whole authority window. In a test that silently dropped all established storage connections for 20 seconds, a v0.1.0-class node fenced; a v0.2.0 node kept serving.
The core event loop owns the lease timer on a dedicated thread. Restores, compaction, and diagnostics cannot delay it.
celld logs each lease attempt at start and at completion, so a storage hang is distinguishable from a timer failure.
Shutdown and restart:
SIGTERM starts a graceful drain. The drain hands each cell to a peer directly, so takeover does not wait for the lease TTL.
POST /shutdown?handoff=preserve on the internal listener prepares a same-node restart. The replacement process resumes its local cell databases and performs no owner or replica reads.
The drain waits for its ownership release writes and bounds each connection, so one idle connection cannot use the full deadline.
The process exits without unwinding. This fixes a crash when a warm node stops.
Storage backends:
A gs:// bucket selects Cloud Storage's generation-based compare-and-swap and authenticates with Application Default Credentials.
A bucket can take a key prefix, so several independent fleets can share one bucket without collisions.
Workers surface:
Wasm modules deploy and load as compiled WebAssembly.Module values. A workers-rs example shows the path, and older...