raft
A battle-tested Go library implementing the Raft consensus protocol for replicated, fault-tolerant state machines.
Repository Health
Technical Analysis
raft is a Go library that manages a replicated log and works with a client-supplied finite state machine (FSM) to build consistent, partition-tolerant distributed systems. It implements the full Raft consensus protocol from leader election and log replication through snapshotting and log compaction, and it’s the consensus engine underneath HashiCorp’s own Consul, Nomad, and Vault.
Rather than bundling storage or networking, the library exposes small interfaces — LogStore, StableStore, SnapshotStore, and Transport — so applications can plug in their own durable storage and RPC layer while raft handles the hard distributed-systems problems: quorum-based commits, leadership transfer, cluster membership changes, and protocol-version negotiation for zero-downtime upgrades across a running cluster.
What You Get
- A complete Raft implementation: leader election, pre-vote, log replication, snapshotting/compaction, and cluster membership changes (AddVoter, AddNonvoter, RemoveServer, DemoteVoter)
- Pluggable persistence via LogStore, StableStore, and SnapshotStore interfaces, with in-memory reference implementations for tests and prototyping
- A pluggable Transport interface with a production TCP implementation and an in-memory transport for unit tests
- Typed Future objects (ApplyFuture, IndexFuture, SnapshotFuture, ConfigurationFuture) giving every async operation a uniform Error()/Response() contract
- Built-in leadership transfer, graceful shutdown, and manual snapshot/restore for disaster recovery
- Protocol-version negotiation that lets a live cluster be upgraded across three historical wire-protocol versions without downtime
Common Use Cases
- Building a distributed key-value store or config store that needs strong consistency across replicas
- Adding leader election and replicated state to a custom database or coordination service
- Implementing a distributed lock manager or service-discovery backend
- Powering the control plane of an infrastructure tool that must survive individual node failures without losing data
Under The Hood
Architecture The library centers on the Raft struct in raft.go, driven by a single main goroutine (r.run) that owns all state transitions, paired with separate goroutines for FSM application (runFSM) and snapshotting (runSnapshots); coordination happens entirely through Go channels (applyCh, fsmMutateCh, fsmSnapshotCh, verifyCh, configurationsCh, bootstrapCh) rather than locks, while hot fields like currentTerm and lastLog live in raftState as atomics for lock-free reads. Storage and networking are abstracted behind small interfaces — LogStore and StableStore for persistence, SnapshotStore for compaction, and Transport for RPC — so swapping a storage backend (BoltDB via a companion repo) or transport (in-memory for tests, TCP in production) requires no change to consensus logic; FSM is the sole interface an application implements to receive committed entries. Client calls flow from Apply/ApplyLog through a logFuture queued on applyCh, get appended and replicated by the main loop, then flow to fsmMutateCh for application to the user’s state machine — a design where the LogStore/Transport/FSM triad is genuinely the load-bearing abstraction: changing it would touch restoreSnapshot, restoreFromCommittedLogs, and the configuration-tracking logic that NewRaft assembles at startup.
Tech Stack
Written in Go (go.mod targets Go 1.25), the module depends on hashicorp/go-hclog for structured logging, hashicorp/go-metrics (with a compatibility shim supporting both armon/go-metrics and hashicorp/go-metrics via build tags) for telemetry, hashicorp/go-msgpack/v2 for binary log and RPC encoding, and stretchr/testify for test assertions — deliberately minimal runtime dependencies otherwise. There’s no bundled database; persistence is left to whatever LogStore/StableStore/SnapshotStore the application supplies, with in-memory implementations shipped for testing and production-grade stores (BoltDB-backed) living in separate raft-boltdb/raft-mdb repositories. Build tooling is a plain Makefile around go test/go vet, with GitHub Actions running CI on every push, and the library is consumed simply by being vendored into other Go binaries such as Consul, Nomad, and Vault.
Code Quality
The repo carries an unusually large test surface for its size — 18 top-level *_test.go files plus a dedicated fuzzy/ subpackage implementing a deterministic simulation-style test harness (cluster.go, partition_test.go, slowvoter_test.go, leadershiptransfer_test.go) that exercises elections, partitions, and leadership transfer under randomized conditions, well beyond typical unit testing. Tests lean on testify’s assert/require, with testing.go/testing_batch.go supplying a shared MakeCluster harness so scenario tests stay declarative. Error handling is explicit and idiomatic: exported sentinel errors (ErrLeader, ErrNotLeader, ErrRaftShutdown, and others in api.go) are returned rather than panicking, though a few internal paths still panic on unexpected log-store corruption as a deliberate fail-fast choice. Naming follows standard Go convention, and CI runs the full suite on every push; no dedicated linter config was found beyond go vet.
API Design The public surface is intentionally small — three entry functions (NewRaft, BootstrapCluster, RecoverCluster) plus a handful of methods on *Raft (Apply, Barrier, VerifyLeader, AddVoter/RemoveServer, Shutdown, Snapshot/Restore) — and every async call returns a typed Future with a uniform Error()/Response() contract, so callers never touch the library’s internal channels directly. Getting started requires implementing one interface (FSM) plus supplying storage/transport interfaces, with in-memory reference implementations provided for prototyping, keeping a toy cluster’s boilerplate small even though production deployments need a durable LogStore from a companion repo. Every exported type carries thorough godoc, including detailed protocol-version migration notes, and docs/apply.md and docs/divergence.md cover deeper operational nuance, though there’s no higher-level tutorial beyond README-linked community examples. Its clearest technical distinction from a from-scratch consensus implementation is the protocol-version negotiation system in config.go, which lets a live cluster be rolled through three historical wire-protocol versions with zero downtime.
Used by 3 apps in this directory
Pyroscope
Monitoring · Devops · Developer Tools
An open-source, horizontally scalable continuous profiling platform that pinpoints CPU, memory, and I/O bottlenecks down to the exact line of code, built by Grafana Labs alongside Loki, Tempo, and Mimir.
tau
Devops
Open-source, Git-native platform-as-a-service for building, deploying, and scaling fullstack apps on your own infrastructure with no DevOps required.
Weaviate
Databases · Search
Open-source vector database combining semantic search, hybrid queries, RAG, and image search in a single cloud-native system built for production scale.