nlbd
No Leader,
.dev
But Distributed.

On consensus without sovereigns

Every distributed protocol begins with a question older than computing itself: how do strangers agree without a sovereign? The proposition seems contradictory — agreement implies arbitration, arbitration implies an arbiter — and yet networks of unaffiliated machines reach the same conclusion thousands of times per second.

The answer is not the absence of authority but its diffusion. Authority becomes weather: a pattern emerging from many independent gusts, none of which is the wind itself.

// quorum.rs

fn propose(value: V) -> Promise<V> {
  let votes = peers
    .broadcast(Phase::Prepare)
    .collect_ge(QUORUM)?;
  if votes.agree() {
    return commit(value);
  }
  retry_with_backoff()
}

No proposer is privileged. A retry from any peer is identical in weight to the original.

Both panels agree: authority is what the network does, not what a node has.

The geometry of disagreement

Disagreement is the substrate, not the failure. A protocol that cannot disagree cannot agree either — agreement is the resolution of a possible-disagreement, and where disagreement is impossible, no information has been added.

Byzantine tolerance is not a defense against malice so much as an acknowledgment that any participant might, in any particular round, be wrong. Including ourselves.

// gossip.go

func Gossip(msg Msg) {
  peers := pickRandom(3)
  for _, p := range peers {
    go p.Send(msg)
  }
  // no leader, no order
  // the message finds itself
}

Three random neighbors. Logarithmic propagation. The network learns by overhearing.

On time, which is also distributed

There is no global now. Each node holds its own clock — a private chronicle of when-things-happened-here — and the network's task is to reconcile these chronicles into a partial order rich enough to act on, but humble enough to admit it is not the truth.

Lamport's insight was that causality is cheaper than synchrony, and almost always sufficient.

// vector_clock.ts

type Clock = Map<NodeId, number>;

function tick(c: Clock, n: NodeId) {
  c.set(n, (c.get(n) ?? 0) + 1);
  return c;
}

function merge(a: Clock, b: Clock) {
  // pointwise max — no winner
  return zipMax(a, b);
}

Pointwise max. The merge keeps the larger memory of every node — no clock dominates.

Theory and practice converge: the protocol is the politics.

Why leaderless

A leader is a single point of optimism — a wager that the most-valuable node will also be the most-available, the most-honest, and the most-correct, simultaneously. Leaderless protocols refuse the wager. They ask, instead, what minimum agreement is sufficient, and what maximum disagreement is survivable.

This is not anarchism. It is engineering humility, expressed as code.

// epaxos.py

def propose(self, cmd):
    # any replica may propose
    deps = self.detect_conflicts(cmd)
    if self.fast_quorum(cmd, deps):
        return self.commit(cmd, deps)
    return self.paxos_accept(cmd, deps)

Any replica. Any time. The fast path is non-leadered; the slow path is leader-equivalent without a leader.

A small library, not a framework

nlbd is a set of composable primitives for leaderless coordination — quorums, vector clocks, gossip, conflict-free types — that you assemble into a protocol the shape of your problem. We do not provide a runtime. We provide vocabulary.

It is unopinionated about transport, storage, and identity. It is opinionated only about leadership: there is none.

// install

$ npm install @nlbd/core
$ cargo add nlbd
$ go get nlbd.dev/core

# first quorum
import { Quorum } from '@nlbd/core';
const q = Quorum.of(5).majority();
q.propose(value);

Three runtimes. One vocabulary. No coordinator.

No leader, but distributed. The split is the design.

nlbd.dev — leaderless primitives for distributed systems