Lesson 7 of 14

CRDTs: G-Counter

Conflict-Free Replicated Data Types (CRDTs)

In an eventually consistent distributed system, replicas can accept writes independently and sync later. This creates conflicts: two replicas might have different values for the same key.

CRDTs (Conflict-Free Replicated Data Types) are data structures designed so that all conflicts can be resolved automatically — merging is always deterministic and produces the correct result.

The G-Counter (Grow-Only Counter)

The simplest CRDT is the G-Counter. It is a distributed counter that can only be incremented. Each node maintains an array of counters — one slot per node. A node only increments its own slot.

class GCounter {
  constructor(nodeId, numNodes) {
    this.nodeId = nodeId;
    this.counts = new Array(numNodes).fill(0);
  }

  increment() {
    this.counts[this.nodeId]++;
  }

  value() {
    return this.counts.reduce((sum, c) => sum + c, 0);
  }

  merge(other) {
    // Element-wise maximum
    for (let i = 0; i < this.counts.length; i++) {
      this.counts[i] = Math.max(this.counts[i], other.counts[i]);
    }
  }
}

Why It Works

  • No conflicts: Each node writes to its own slot — no contention.
  • Merge is idempotent: merging twice gives the same result as once.
  • Merge is commutative: merging A into B gives the same result as merging B into A.
  • Merge is associative: (A merge B) merge C = A merge (B merge C).

These properties mean replicas can sync in any order, at any time, and always converge to the same value.

Real-World Uses

  • Redis CRDT — distributed Redis instances use CRDTs for conflict-free replication.
  • Riak — uses CRDTs for sets, maps, and counters.
  • Collaborative editing — operational transforms and CRDTs power Google Docs-style real-time collaboration.

Your Task

Implement a GCounter class with increment(), value(), and merge(other) methods.

JavaScript loading...
Loading...
Click "Run" to execute your code.