WARaft: the Raft implementation WhatsApp ran in production
An Erlang implementation of RAFT from WhatsApp
At a glance
- What is it?
- WARaft is an Erlang implementation of the Raft consensus algorithm that served as a consensus component in WhatsApp's large-scale message storage systems, and it separates the algorithm from the storage, log, transport and metrics so a production service can supply its own durable pieces.
- Who is it for?
- WARaft fits a team running an Erlang or OTP service that needs a replicated log with leader election, strongly consistent reads and membership changes, and it fits anyone who wants to read a production-shaped Raft implementation rather than a teaching one.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 3 days ago.
- What is it written in?
- Mainly Erlang, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What WhatsApp actually ran on it
WARaft is an Erlang implementation of the Raft consensus algorithm for building replicated state machines, and the project states that it has served as a consensus component in WhatsApp's large-scale, strongly consistent message-storage systems. That sentence is the reason to read the source rather than just the algorithm description. A consensus library that has carried real message traffic has been shaped by the awkward parts, membership changes during failures, log truncation, snapshots that have to line up with a distributed log, and the boring question of what happens when a partition comes back. The code lives in the WhatsApp GitHub organisation, is licensed under Apache 2.0, and was last pushed to on 2026-10-20, with the repository publishing no GitHub releases. The Erlang implementation and the OTP supervision model are the substrate everything else is built on, and the release history being empty means you would vendor a commit rather than pull a version.
The feature list, and the pluggable boundaries
The features are grouped into three kinds, and the second group is the one that makes this a library rather than an application. First come the Raft mechanics: leader election, replicated logs, strongly consistent reads, snapshots and membership changes, including support for non-voting participants and witnesses. Then come the pluggable implementations, for the replicated state machine, the log, the Raft RPC distribution, the snapshot transport, the log labels and the metrics. Then the storage-oriented controls, such as command batching, high- and low-priority queues, configurable backpressure and optional leader read leases. That separation is the architecture. A consensus implementation that owns its log and its transport is useful to exactly one service, while one that exposes those as interfaces is usable by any service that has a durable log and a way to talk to its peers.
Building and running the checks
WARaft requires Erlang/OTP 28, and the build and its checks go through Rebar3.
rebar3 compile
rebar3 ct
rebar3 do dialyzer, xrefThe three commands are the whole check suite and they are worth reading as a statement of what a consensus library needs. Common Test for behaviour, Dialyzer for the type errors that matter in a system where a message mismatch causes a silent split-brain, and xref for unused and undefined function calls, which in an Erlang codebase with heavy dynamic dispatch is not a cosmetic check. The repository layout is compact: src/ for the implementation, include/ for headers, test/ for the suites, examples/ for the key-value store, plus a rebar.config. The OTP 28 requirement is worth noting, since it is recent enough that it narrows which environments you can run this in.
The quick start session, and the stalled state before bootstrap
The documentation walks through an Erlang shell session that starts a single-node cluster, then writes and reads a value. The first step loads the WARaft records and starts the application.
rr(wa_raft_server).
application:ensure_all_started(wa_raft).Then it gives the host application a unique data directory for the run, using a timestamp so two runs do not collide.
application:set_env(
test_app,
raft_database,
filename:join(
"/tmp",
"wa_raft_quick_start_" ++ integer_to_list(erlang:system_time(microsecond))
)
).The supervisor is started and partition 1 of the table test is added, and the comment on the next step is the one that matters for understanding the API. A new partition remains stalled until it receives its initial configuration, which the status call confirms by returning stalled, and a successful single-member bootstrap then makes that server the leader.
wa_raft_server:status(raft_server_test_1, state).
Config = wa_raft_server:make_config([
#raft_identity{name = raft_server_test_1, node = node()}
]).
wa_raft_server:bootstrap(
raft_server_test_1,
#raft_log_pos{index = 1, term = 1},
Config,
#{}
).
wa_raft_server:status(raft_server_test_1, state).The commit and the read go through the acceptor, and the read returns the value that was written.
wa_raft_acceptor:commit(
raft_acceptor_test_1,
{make_ref(), {write, test, key, 1000}}
).
wa_raft_acceptor:read(raft_acceptor_test_1, {read, test, key}).The process tree, and who calls what
The architecture paragraph in the project overview is dense and worth unpacking. The wa_raft application starts services shared by all partitions, and a host application owns a wa_raft_sup supervisor. Each partition runs a one-for-all process tree containing its queue, storage, log, Raft server, client acceptor and transport cleanup worker. The API splits along those lines too. Applications submit reads and commits through wa_raft_acceptor, they perform membership and lifecycle operations through wa_raft_server, and they use wa_raft_info for local leader and health lookups. The one-for-all choice inside a partition is a meaningful design statement, since it means a partition's processes restart together rather than independently, which is the conservative choice when they share a log.
Multi-node deployment, and the example that is not a database
A multi-node deployment starts the same partition on every participating node, installs the same membership configuration on each replica, and then triggers an election. That is the standard Raft deployment shape, and the project spells it out because the ordering matters and because a partition that is started but never bootstrapped sits stalled. The key-value store example illustrates partition routing and the storage callbacks, and the project is careful to label it a teaching example rather than a production-ready distributed database. That distinction is the important caveat in the whole repository. The ETS log and storage providers that ship by default are intended for examples and tests, and they are not durable across VM restarts, which means a production deployment must supply durable providers. What the example demonstrates is the shape of the callbacks, not the shape of a database.
Editorial conclusion
WARaft fits a team running an Erlang or OTP service that needs a replicated log with leader election, strongly consistent reads and membership changes, and it fits anyone who wants to read a production-shaped Raft implementation rather than a teaching one. It does not fit a team that expects the default providers to be durable, because the ETS log and storage providers are intended for examples and tests and do not survive a VM restart, so production deployments must supply durable providers. It also does not fit someone wanting a finished key-value store, since the examples/kvstore project is described as a teaching example rather than a production-ready distributed database. Before you build on it, decide which of the pluggable components you will replace, and expect Erlang/OTP 28 and Rebar3 as the toolchain.
Frequently asked questions
What is WARaft and where has it been used?
WARaft is an Erlang implementation of the Raft consensus algorithm for building replicated state machines, and the project states it has served as a consensus component in WhatsApp's large-scale, strongly consistent message-storage systems.
How do I build WARaft and run its checks?
WARaft requires Erlang/OTP 28. With Rebar3 the commands are rebar3 compile to build, rebar3 ct to run the Common Test suites, and rebar3 do dialyzer, xref for the type and cross-reference analysis.
Are the default ETS log and storage providers durable?
No. The default ETS log and storage providers are intended for examples and tests and are not durable across VM restarts, so production deployments must supply durable providers. The key-value store in examples/kvstore is described as a teaching example rather than a production-ready distributed database.
What can be plugged into WARaft?
The replicated state machine, the log, the Raft RPC distribution, the snapshot transport, the log labels and the metrics are all pluggable, alongside storage-oriented controls such as command batching, high- and low-priority queues, configurable backpressure and optional leader read leases.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/whatsapp-waraft)Was this useful?