Recipe

CRDT Primer

Conflict-free Replicated Data Types let multiple replicas converge to the same state without coordination. Meridian uses CRDTs internally to merge concurrent agent edits across the swarm, so you can think of this primer as the mental model behind every collaborative write your workers issue against shared state.

1.What converges, and why

A CRDT guarantees strong eventual consistency: if every replica sees the same set of operations, all replicas arrive at the same value, regardless of delivery order. There are two flavors. State-based CRDTs (CvRDTs) ship merged state and rely on a join semilattice. Operation-based CRDTs (CmRDTs) ship operations over a causal-broadcast channel. Meridian leans state-based for snapshot sync and op-based for live cursors.

2.Building blocks you will reach for

  • G-Counter — grow-only counter, merge by per-replica max.
  • PN-Counter — two G-Counters for plus and minus.
  • OR-Set — observed-remove set keyed by unique tags.
  • LWW-Register — last-writer-wins via Lamport timestamp.
  • RGA / Yjs Doc — sequence CRDT for collaborative text.

3.A minimal G-Counter in TypeScript

The merge operation is associative, commutative, and idempotent. Those three properties are the contract that lets two replicas exchange state at any time, in any order, and still agree on the final value.

type GCounter = Record<string, number>;

function increment(c: GCounter, id: string): GCounter {
  return { ...c, [id]: (c[id] ?? 0) + 1 };
}

function value(c: GCounter): number {
  return Object.values(c).reduce((a, b) => a + b, 0);
}

function merge(a: GCounter, b: GCounter): GCounter {
  const out: GCounter = { ...a };
  for (const k of Object.keys(b)) {
    out[k] = Math.max(out[k] ?? 0, b[k]);
  }
  return out;
}