← Back to blog

CRDTs from Scratch, Part 3: Use Cases, Libraries, and the Limits

Where CRDTs ship today (Yjs, Automerge, Loro, Riak, Redis), the metadata and invariant costs, and when not to reach for one.

#crdts#distributed-systems#libraries

The final part of a three-part series. Part 1 built the theory; Part 2 implemented the classic CRDTs in Go. Here we connect them to the systems that ship them, and talk honestly about where they fall short.


The theory is elegant, but the reason CRDTs left the academic papers and ended up in software you use every day is that they solve an expensive, recurring problem: letting many replicas write freely and still agree, without a coordinator in the hot path. Here’s where that pays off.

Real-world use cases

Collaborative editing and local-first apps

This is the marquee use case. Google-Docs-style editing, Figma’s multiplayer canvas, Notion’s offline mode, code editors with shared cursors: all need many people (and the same person across devices) editing the same document, often offline, with edits merging seamlessly when they reconnect. A sequence CRDT (Part 2) gives every keystroke a stable identity so concurrent inserts interleave deterministically.

The architectural payoff is that the server doesn’t need merge logic at all. Each client holds the full document replica and edits locally; the server (or a peer-to-peer link) just stores and forwards updates. Convergence is guaranteed by the data type, not the topology, which is exactly what the “local-first software” movement (coined by Ink & Switch, the lab behind Automerge) argues for: software that keeps working offline, syncs without a central authority, and doesn’t hold your data hostage in someone else’s cloud.

Local-first collaborative editor: clients hold full replicas, the relay just forwards Local-first collaborative editor: clients hold full replicas, the relay just forwards

Distributed databases and caches

CRDTs are baked into datastores that prioritize availability across regions:

  • Riak ships CRDTs (“Riak Data Types”: counters, sets, maps, registers, flags) as first-class values, so multi-datacenter writes converge without read-repair conflicts.
  • Redis Enterprise uses CRDTs under the hood for its active-active geo-replication (“CRDBs”), letting the same key take writes in multiple regions simultaneously.
  • Azure Cosmos DB and several other globally-distributed stores use CRDT-style merge for multi-region write modes.
  • AntidoteDB is a research-grade database built entirely around CRDTs with transactional causal consistency.

Caches, presence, counters, and metrics

Anywhere you want availability over strict accuracy: “likes” and view counts (PN-Counters), online-presence and feature-flag sets (OR-Sets), shopping carts (the original Dynamo example: a set that should never lose an item your user added). These tolerate brief divergence and benefit hugely from never blocking a write.

Edge, IoT, and intermittently-connected systems

Devices that spend most of their life disconnected (vehicles, sensors, field equipment, mobile apps in poor coverage) can keep recording locally and reconcile opportunistically when a link appears. CRDTs are a natural fit precisely because they assume the network is unreliable and out-of-order by default.

The library landscape (2026)

Unless you’re writing a database, you should use a library rather than hand-roll the sequence logic from Part 2. The mature ecosystem is in JavaScript/TypeScript and Rust, and three names dominate.

LibraryLanguage / bindingsBest atNotes
YjsJavaScript (with WASM)Collaborative text/rich-text editingThe production default. Largest ecosystem, smallest bundle, ready-made bindings for ProseMirror, TipTap, CodeMirror, Monaco, Slate. ~920K weekly downloads.
AutomergeRust core, JS/other bindingsJSON-like documents with full historyFeels like editing plain objects; Git-style change history and time-travel. Backed by Ink & Switch; Automerge 2.0 moved the core to Rust for a large performance jump.
LoroRust, JS bindingsHigh performance, rich text + movable treeNewest of the three, built on a Replayable Event Graph; fastest in benchmarks but the youngest ecosystem.

Worth knowing about beyond the big three: Collabs (a TypeScript toolkit for composing and extending custom CRDTs), Diamond Types (experimental, pushing the performance/memory frontier for text), Yrs (the official Rust port of Yjs), and Y-Sweet / Liveblocks / PartyKit / ElectricSQL, which package CRDT sync infrastructure (servers, persistence, presence) so you don’t have to operate it yourself.

A practical rule of thumb: reach for Yjs if you’re building an editor and want the richest binding ecosystem today; Automerge if you think in whole documents with history and want a clean JSON-like API; Loro if raw performance is the deciding factor and you can tolerate a younger ecosystem.

The costs: read this before you commit

CRDTs are not free, and the failure mode of adopting them naively is real. Three honest caveats:

1. Metadata and tombstone growth

Every guarantee in Part 2 was bought with bookkeeping: per-replica counters, version vectors, unique tags, and, most painfully, tombstones for deleted elements. In a long-lived collaborative document, the tombstones for every character ever typed and deleted can dwarf the live content. Libraries fight this with compression, run-length encoding of IDs, and garbage collection, but safe tombstone GC in a system where an offline replica might still reference a “deleted” element is a genuinely hard distributed-systems problem. Budget for it; don’t assume it’s solved for your access pattern.

2. CRDTs converge values, not invariants

This is the conceptual trap. A CRDT guarantees every replica reaches the same value, but it cannot enforce a constraint that spans the merge: “balance must stay ≥ 0,” “only one user holds this username,” or “no more seats sold than exist.” Those are exactly the invariants that need coordination, and coordination is the thing CRDTs are designed to avoid. If your domain has hard invariants, CRDTs belong only on the parts that don’t, and you’ll need consensus (Raft/Paxos) or transactions for the parts that do. Some systems (like AntidoteDB, and the research on “Invariant-preserving applications” / RedBlue consistency) blend the two: coordinate only on operations that could violate an invariant, run everything else CRDT-style.

3. Convergence is consistent, not necessarily correct

When two users concurrently set a title to different strings, a CRDT picks deterministically (LWW) or keeps both (MV), but it can’t know which the humans intended. Convergence is a syntactic guarantee. For text, interleaving concurrent edits can occasionally produce a merged result no human would have written (the well-documented “interleaving anomaly” in sequence CRDTs). The data type guarantees agreement, not good taste.

When (not) to reach for a CRDT

Good fit: offline-first and local-first apps; real-time collaboration; multi-region active-active writes; presence, counters, and caches that value availability over momentary precision; intermittently-connected edge/IoT systems.

Poor fit (or use sparingly): anything with hard cross-key invariants (banking balances, inventory limits, unique constraints); workloads where a single writer or a quick consensus round is perfectly affordable (a Raft-backed store is simpler and gives you stronger guarantees); and cases where the metadata overhead would dwarf tiny, rarely-conflicting data.

The honest summary across all three parts: CRDTs move correctness out of your network plumbing and into your data types, buying availability and offline capability at the cost of metadata and the inability to enforce global invariants. When that trade matches your problem, they’re close to magic. When it doesn’t, reaching for one adds complexity without buying the guarantee you actually needed. Knowing the difference (which is what this series was really about) is the whole skill.


References and further reading

All diagrams in this series were drawn by hand (SVG, rendered to animated GIF) for the articles; no third-party images were used.

Foundational papers

  • Marc Shapiro, Nuno Preguiça, Carlos Baquero, Marek Zawirski. Conflict-free Replicated Data Types. SSS 2011. (The paper that named the field and defined Strong Eventual Consistency.)
  • Shapiro, Preguiça, Baquero, Zawirski. A comprehensive study of Convergent and Commutative Replicated Data Types. INRIA Research Report RR-7506, 2011. (The exhaustive catalogue of CRDT designs: counters, registers, sets, sequences.)
  • Carlos Baquero, Paulo Sérgio Almeida, Ali Shoker. Making Operation-based CRDTs Operation-based. / Delta State Replicated Data Types (JPDC, 2018). (The delta-state optimization referenced in Part 1.)
  • Nuno Preguiça. Conflict-free Replicated Data Types: An Overview. 2018. (Accessible survey.)
  • Hyun-Gul Roh et al. Replicated Abstract Data Types: Building Blocks for Collaborative Applications. JPDC 2011. (The RGA sequence CRDT used in Part 2.)
  • Martin Kleppmann, Alastair Beresford. A Conflict-Free Replicated JSON Datatype. IEEE TPDS 2017. (Composing CRDTs into JSON documents.)
  • Mehdi Bouaziz / Stéphane Weiss et al. Logoot and Treedoc sequence-CRDT papers (alternatives mentioned in Part 2).
  • Kleppmann et al. Local-First Software: You Own Your Data, in Spite of the Cloud. Ink & Switch, 2019. (The manifesto behind the local-first use case.)

Books

  • Martin Kleppmann. Designing Data-Intensive Applications (O’Reilly, 2017); Chapter 5 on replication and the conflict-resolution discussion frame CRDTs in context.
  • Carlos Baquero & Nuno Preguiça (eds.). Surveys and lecture notes on replicated data types (freely available via the authors’ pages).

Documentation and library sources

Talks worth watching

  • Martin Kleppmann, CRDTs: The Hard Parts (2020): the clearest public talk on tombstones, interleaving, and the engineering realities covered in Part 3.
  • Marc Shapiro’s original CRDT lectures (INRIA).

Library statistics (download counts, performance characteristics, ecosystem maturity) reflect the landscape as of mid-2026 and will drift; check the current docs before choosing.