Beyond Code & Karma · Distributed Systems
Many replicas edit the same data offline, then merge in any order — and all land on the same state, with no server, no locks, no conflicts. The maths of strong eventual consistency, and the Advaita truth that beneath the many is one.
Chapter 01 — The Foundation
A CRDT — Conflict-free Replicated Data Type — is a data structure many replicas can update independently, even while disconnected, then merge automatically with no central coordinator and no conflicts. The guarantee is strong eventual consistency: once every replica has seen the same set of updates, they are byte-for-byte identical — regardless of the order in which those updates arrived.
The Cosmic Connection
In Advaita (non-duality), the countless individual souls — the jīvas — each perceive a separate, partial world. That sense of separateness is māyā. Beneath all of them is a single reality, Brahman. A CRDT is exactly this metaphysics, made mechanical: the replicas are the jīvas, the merge is the recognition that the many were always one, and convergence is the realization that — whatever the order of actions — all paths reach the same truth.
"The commutative, associative, idempotent laws are niṣkāma karma: action whose fruit does not depend on the order it was done."
Chapter 02 — Why It Works
The entire guarantee rests on the merge function having three algebraic properties. With all three, the reachable states form a mathematical join-semilattice and convergence is forced — no locks, no consensus, no server arbitrating who wins.
merge(a, b) === merge(b, a). Order of merging two
replicas doesn't matter — peers that synced in different orders
still agree.
merge(merge(a, b), c) === merge(a, merge(b, c)).
Grouping doesn't matter when three or more replicas combine.
merge(a, a) === a. Merging the same state twice changes
nothing — a duplicated or re-delivered message is
harmless.
A grow-only counter keeps one slot per replica; each replica only ever increments its own slot. The value is the sum of slots, and the merge is element-wise max — which is commutative, associative, and idempotent for free:
// A G-Counter: one slot per replica — you only ever increment YOUR slot. class GCounter { constructor(id, peers) { this.id = id; this.p = {}; // replicaId → count peers.forEach(r => this.p[r] = 0); } inc() { this.p[this.id]++; } // local, offline-safe value() { // sum across all slots return Object.values(this.p).reduce((a, b) => a + b, 0); } // merge = element-wise MAX — commutative, associative, idempotent merge(other) { for (const r in other.p) this.p[r] = Math.max(this.p[r], other.p[r]); } }
Chapter 03 — The Zoo
There are two ways to build a CRDT, and a small zoo of standard shapes built on top of them.
A naive set can't tell "I removed this" from "you re-added it concurrently". An OR-Set tags every add and only tombstones the tags it has actually observed — so add and remove commute:
// OR-Set (Observed-Remove Set): every add carries a unique tag. // remove() only tombstones the tags it has SEEN — never future ones. add(elem) { this.adds.push({ elem, tag: uid() }); // e.g. "x@3:A" } remove(elem) { for (const a of this.adds) if (a.elem === elem) this.removed.add(a.tag); // tag-level tombstone } // present iff some add-tag is not in 'removed' — so add ⟂ remove has(elem) { return this.adds.some( a => a.elem === elem && !this.removed.has(a.tag)); }
Chapter 04 — Live Visualization
A G-Counter on two replicas. Each increments its own slot while offline, so they disagree — then a single merge (element-wise max) converges both to the same total, no matter who counted what.
Chapter 05 — The Convergence Dance
Each replica applies local edits with no coordination. States drift apart — and that's allowed.
When connectivity returns, replicas gossip their state (or their ops) to one another — in any order.
The commutative, associative, idempotent merge combines any two states deterministically. No arbitration.
All replicas that have seen the same updates are now identical. Strong eventual consistency, reached.
| CRDT type | Converges on |
|---|---|
| G-Counter | Per-slot maxes, summed — a grow-only count |
| PN-Counter | Two G-Counters (P − N) — supports decrements |
| OR-Set | Present iff an unremoved add-tag exists — add wins |
| LWW-Register | The value with the highest timestamp |
| RGA / Sequence | One deterministic character order, by unique id |
| CRDT | OT (Operational Transform) | |
|---|---|---|
| Coordination | None — peer-to-peer, offline-first | Usually a central server |
| Conflicts | Impossible by construction (commutative merge) | Transform ops against concurrent ops |
| Cost | Metadata: unique ids + tombstones | Tricky transformation functions |
Chapter 06 — Deep Dive
This is where the surface-level explainers stop. Here's what actually matters when you ship convergent state.
A delete can't simply drop an element, because a concurrent insert on another replica may reference it as its anchor — removing it outright would break convergence or resurrect the wrong order. So a delete marks the element as a tombstone: present in the structure, hidden from the visible text. Karma is never truly erased, only marked. Tombstones do accumulate, but production libraries garbage-collect them once every replica has provably seen the delete (via version vectors), and they pack runs of ids — so real documents don't grow without bound.
Treat a whole document as one LWW value and you keep only the version with the latest timestamp — so one replica's edit is silently clobbered. That's the ego overwriting another's act. LWW is perfectly fine for a single scalar (a user's status, a last-seen time) where losing the older write is acceptable, but for a shared sequence it destroys work. A sequence CRDT keeps both edits — which is exactly the difference the full visualizer lets you toggle.
Collaborative text is the hard case because position is relative — if I insert at index 3 and you delete at index 1 concurrently, our indices no longer agree. Sequence CRDTs (RGA, LSEQ, Yjs's YATA, Treedoc) give every inserted character a globally unique id (replica id + counter) and record the element it was inserted after, not a numeric index. Concurrent inserts at the same spot are ordered deterministically by comparing ids, so no character is lost and every replica computes the identical sequence.
Anywhere replicas must stay coherent without a coordinator:
| System | What it uses CRDTs for |
|---|---|
| Collaborative editors | Figma, Linear, and editors on Yjs / Automerge for real-time multiplayer. |
| Local-first apps | Note-taking and mobile apps that sync when connectivity returns — no merge dialogs. |
| Distributed databases | Redis (Active-Active), Riak, and AntidoteDB for multi-region writes without coordination. |
| Caches & presence | Counters, sets, and registers replicated across regions with eventual agreement. |
Chapter 07 — Dharma & Convergence
Niṣkāma karma is action performed without attachment to the order or fruit of the deed. A CRDT merge is precisely this discipline: each replica acts of its own will, apart from the others — yet the merge is the impartial law of dharma, judging no order and discarding no act.
// Each replica acts alone, of its own will… replicaA.inc(); // your action, recorded only in your slot replicaB.inc(); // her action, recorded only in hers // …yet the merge judges no order and loses no act. a.merge(b); // === b.merge(a) — commutative: the law is impartial a.merge(b); // again? no change — idempotent: nothing counts twice // all paths reach the one reading. moksha = convergence.
To overwrite another's edit with your own — last-write-wins — is the ego asserting itself. Convergence is its opposite: the surrender into a shared truth, where every act is honoured and the final reading is the same whatever the path taken to reach it. Many hands, one truth.
"As scattered rivers reach one sea, so do all replicas reach one state — order forgotten, nothing lost." 🙏
Chapter 08 — Test Yourself
Three questions. No coordination allowed. Your karma is watching.
The Enlightenment
कर्म करो, फल की चिंता मत करो