A modern C++ implementation of the RAFT consensus algorithm.
- Batteries-included orchestration:
Raftorprovides a single-threaded event loop, ready-processing, and thread-safe proposal / read APIs out of the box. - Production-grade persistence & networking: Built-in segmented WAL with CRC32C and a pluggable Cap'n Proto RPC transport layer.
- Extensively tested: Unit tests, data-driven tests, and continuous ASan / TSan coverage on both x64 and ARM64.
- Core consensus — Full state machine with Follower, Candidate, PreCandidate, and Leader roles.
- Log management —
RaftLogcombines an in-memory unstable buffer with a pluggableStorageinterface (MemoryStorage,WALStorage, or custom). - Dynamic membership — Safe cluster configuration changes via joint consensus (
ConfChanger,JointConf,MajorityConf). - Linearizable reads —
ReadOnlyqueue and read-index support for consistent read operations. - High-level orchestration —
Raftormanages the Raft lifecycle, ready processing, proposal tracking (callbacks, futures, sync variants), and snapshot flow. - Write-Ahead Log — Segmented log files with CRC32C checksums, fast index lookup, and snapshot-based compaction.
- Pluggable RPC — Abstract
Transportinterface with a Cap'n Proto implementation (CapnpTransport). - Modern C++ — C++17,
nonstd::expectederror handling (Result<T, E>), and doctest test framework.
- CMake >= 3.28
- Ninja
- C++17 compiler (Clang or GCC)
- Task (optional, for convenience commands)
Using Task:
task cmake # configure
task build # build tests
task test # build & run all testsOr with CMake directly:
cmake --preset=Debug -B build
cmake --build build
./build/tests/raftpp-tests
./build/tests/datadriven/data-driven-testsraftpp builds and runs without Seastar by default. Optional Seastar build
support is opt-in with RAFTPP_WITH_SEASTAR=ON, for example:
cmake --preset=Debug-Seastar -B build-seastarWhen enabled, CMake expects an installed Seastar package discoverable via the
normal package search path, such as CMAKE_PREFIX_PATH; Seastar is not fetched
as part of the default build. The non-Seastar public API remains the
compatibility baseline, and Seastar integration is experimental until runtime
and transport support lands.
#include "raftpp/raftor/raftor.h"
class MyStateMachine : public raftpp::raftor::StateMachine {
public:
raftpp::Result<raftpp::raftor::ApplyResult> Apply(
const raftpp::Entry& entry) override {
return raftpp::raftor::ApplyResult{.response = "ok"};
}
// ... TakeSnapshot / RestoreSnapshot
};
int main() {
raftpp::raftor::RaftorConfig config;
config.node_id = 1;
config.listen_addr = "127.0.0.1:9001";
config.data_dir = "./data";
config.tick_interval = std::chrono::milliseconds(100);
auto raftor = raftpp::raftor::Raftor::Create(
config, std::make_unique<MyStateMachine>());
if (!raftor) { return 1; }
if (auto result = (*raftor)->Start(); !result) { return 1; }
// Drive the event loop...
for (int i = 0; i < 20; ++i) {
(*raftor)->Poll(config.tick_interval);
if ((*raftor)->GetStatus().role == raftpp::StateRole::Leader) {
(*raftor)->Stop();
return 0;
}
}
return 1;
}See examples/minimal_node/ for the complete runnable version.
| Example | Description |
|---|---|
examples/minimal_node/ |
Single-node bootstrap that elects itself leader. |
examples/kvstore/ |
Distributed key-value store with an HTTP frontend and multi-peer Raft cluster. |
┌─────────────────────────────────────────┐
│ Application (StateMachine, Proposals) │
├─────────────────────────────────────────┤
│ Raftor (event loop, ready processor, │
│ proposal tracker) │
├─────────────────────────────────────────┤
│ Core Raft (RawNode → Raft → RaftLog) │
├─────────────────────────────────────────┤
│ WAL + RPC Transport │
└─────────────────────────────────────────┘
- Core (
include/raftpp/core/) — Low-level consensus primitives:RawNode,Raft,RaftLog,Storage,ProgressTracker,ReadOnly, and configuration changers. - Orchestration (
raftor/) —Raftorties everything together with a tick-driven event loop,Readyprocessing, and user-friendlyPropose/ReadIndexAPIs. - I/O & Persistence (
raftor/wal/,raftor/rpc/) — Durable segmented WAL and a pluggable RPC layer (Cap'n Proto built-in).
- Unit tests —
build/tests/raftpp-tests(15+ test files, doctest-based). - Data-driven tests —
build/tests/datadriven/data-driven-tests(text-based DSL for quorum and confchange scenarios). - Sanitizers — AddressSanitizer and ThreadSanitizer runs on every PR via GitHub Actions.
- Coverage —
llvm-covreports uploaded to Codecov.
Full documentation, guides, and API references are available at:
MIT License. See LICENSE.