Applications of Byzantine Consensus
Marton Trencseni - Sat 23 August 2025 - Distributed
Introduction
In the previous articles — Lamport's Byzantine Generals algorithm in Python and A more general implementation of Lamport's Byzantine Consensus algorithm in Python — I looked at how Lamport’s Byzantine Generals algorithm can be generalized: values can be arbitrary strings (not just attack or retreat), timeouts and default values can be handled cleanly, and multiple rounds can run concurrently with different initiators (“kings”). This naturally raises a bigger question: What kinds of real-world problems is Byzantine Consensus actually useful for?
At first sight, it looks like it could be a silver bullet for distributed systems: if nodes can always agree despite traitors, isn’t this the universal tool for databases, distributed control systems, and safety-critical hardware? As we’ll see, not quite. The Byzantine Generals algorithm in its original oral messages form solves one very specific problem: ensuring that all non-faulty nodes agree on the same value, even when some nodes behave arbitrarily. Importantly, the algorithm makes no judgment about the correctness of that value — it could be attack, retreat, launch, abort, or even a malicious transaction. The only guarantee is consistency among the honest nodes.
It’s worth noting up front that this discussion is limited to the oral-messages algorithm as originally presented by Lamport, Shostak, and Pease. Later members of the Byzantine Fault Tolerance (BFT) family — such as PBFT, Tendermint, and HotStuff — extend the model with additional properties like validity and liveness guarantees, which make them practical for databases and blockchains. Here, however, we’ll stay focused on Lamport’s original formulation and its direct applicability.
Let’s step through some possible applications to see where the algorithm applies, where it doesn’t, and why.
Disclaimer: I don’t work with Byzantine Consensus protocols or aerospace control systems — the examples in this article are purely thought experiments to illustrate the applicability of Lamport’s original oral-messages algorithm.
Distributed databases: not applicable
A tempting example is a replicated database with $N$ nodes, each storing a full copy of the data. Suppose clients can connect to any node and issue commands such as:
Move $100 from Alice’s account to Bob’s account
Now imagine one node is faulty or malicious, perhaps hacked. Instead of forwarding the client’s original command, it changes it to:
Move $1,000,000 from Alice’s account to the hacker’s account
At first this looks like a perfect fit for Byzantine Consensus. The traitor is trying to mislead the others, and as long as $N \geq 3M+1$, Lamport’s algorithm ensures the loyal replicas can outvote the liars.
But here’s the catch: any node can act as the initiator (the “king”) and issue new commands. If the malicious node simply originates the bad command itself — without tampering in transit — then the algorithm happily treats it as a legitimate proposal. From the protocol’s point of view, there’s no difference between the two commands above; both are valid values to agree on.
This is a fundamental limitation: the original Byzantine Generals algorithm is concerned only with agreement, not with validity. In Lamport’s story, both attack and retreat are equally valid outcomes — the only requirement is that all loyal generals do the same thing. There is no concept of a “bad value.”
In practice, this means that using Lamport’s oral-messages algorithm directly for databases does not protect against malicious clients or faulty leaders. If we try to work around this by assuming the initiator (the “king”) is always honest, the problem evaporates — but so does the need for Byzantine Consensus; all nodes could simply follow the king’s command without additional checks.
This is why modern Byzantine Fault Tolerant (BFT) protocols like PBFT, Tendermint, and HotStuff extend Lamport’s ideas with validity conditions: they require that if all honest nodes propose the same client request, it must be chosen; and they usually layer in client authentication, signatures, and transaction semantics. Only with these extensions do BFT protocols become useful in databases and blockchains.
So: Lamport’s original algorithm illustrates the problem beautifully, but on its own, it is not applicable to databases.
Rocket launch: not applicable
A second example often raised is spacecraft launch control. Imagine a rocket with four boosters, each with sensors feeding into small flight computers. Based on temperature, pressure, or other telemetry, each flight computer decides either LAUNCH
or ABORT
.
This sounds close to the Byzantine Generals story: if some boosters launch while others do not, the rocket would flip over and explode. We want all boosters to do the same. But in practice, engineers can afford to design such systems differently:
- Majority voting is simpler. If each sensor’s output is visible to all flight computers, they can just take a majority vote on the raw signals. No need for a recursive message cascade.
- Fail-stop is safer. If even one reading differs wildly, the safe choice is always to abort. There is no pressure to launch in the face of disagreement.
- Faulty computers are themselves dangerous. If a flight computer sends a wrong value, that itself is cause to abort, not to attempt consensus.
The key distinction is that Lamport’s algorithm requires that a decision must be made — attack or retreat, launch or abort — regardless of faulty behaviour. For rockets, that assumption is backwards: engineers explicitly want the option to stop the process if there’s disagreement.
So while the analogy is appealing, in real-world launch control Byzantine Consensus is not the right tool.
Space shuttle flight: a good use-case
Now let’s turn to an example where Byzantine Consensus is directly relevant: redundant flight control computers (FCCs) on an aircraft or space shuttle.
Suppose there are 4 FCCs, each with its own independent sensors. Every 10 ms cycle, they take readings from their own sensors, and decide how they want to move the control surfaces. Let's model the control surfaces as two flaps, one on the left wing, one on the right wing. For simplicity, assume there are only two commands (implemented as voltages on a wire) possible: INCREASE
or DECREASE
the flap angle. We want all control surfaces to perform the same action, so non-faulty FCCs always send the same command to both left and right-side flaps. Each flap actuator receives 4 input wires, one from each FCC. A hardware circuit on the actuator runs majority()
on these inputs — let's assume that in case of a tie, majority() → DECREASE
. The idea is that if one FCC is faulty, it will be outvoted by the other three. We want both left and right wing flaps to perform the same action, INCREASE
or DECREASE
.
Let's imagine a scenario where FCC-0, FCC-1 and FCC-2 are not faulty, but disagree, and faulty FCC-3 sends different commands to different actuators:
- FCC-0:
INCREASE
- FCC-1:
INCREASE
- FCC-2:
DECREASE
(different!) - FCC-3 (faulty):
INCREASE
to the right flap,DECREASE
to the left flap
What happens?
- The right flap sees
[INCREASE, INCREASE, DECREASE, INCREASE]
, somajority([...]) → INCREASE
- The left flap sees
[INCREASE, INCREASE, DECREASE, DECREASE]
, somajority([...]) → DECREASE
Result: the left and right flaps move in opposite directions. The shuttle becomes destabilized, even though there was a majority mechanism at each actuator. This is the subtle but crucial point: hardware majority voting at the actuators is not sufficient when a Byzantine node can equivocate. Each actuator may be consistent locally, but across actuators the system diverges, due to non-faulty nodes disagreeing (FCC-0 and 1 vs FCC-2), and faulty nodes (FCC-3) sending different signals to left and right wings.
The fix is for the FCCs themselves to run the Byzantine Consensus algorithm before sending anything to the actuators — in the above case, even if FCC-3 is faulty, FCC-0, 1 and 2 would agree on either INCREASE
or DECREASE
at the end of the algorithm and send that to the flaps, so both flaps would receive that value on 3 out of 4 of their wires. Even if the decision is not always optimal — say the consensus settles on DECREASE
when INCREASE
would have been slightly better — the cycle runs 100 times per second. In subsequent cycles, the FCCs can converge on the right adjustment. The key property is safety (no divergent flaps), not perfect optimality at every instant.
Who is king?
One more question is: who initiates the consensus round each cycle?
- Option 1: All initiate. Each FCC acts as king once per cycle, proposing its own reading. This leads to four rounds per cycle. Afterward, each FCC applies
majority()
to the set of agreed values. This maximizes resilience, since no single faulty initiator can dominate. Note that in this scenario,majority()
is used both by FCCs and by the wing actuators. - Option 2: Rotate the king. Only one FCC initiates each cycle, and the role rotates. This is cheaper but less safe: one-quarter of the time the faulty FCC will be king, and the system may take a suboptimal action. However, the algorithm still ensures consistency, and later cycles can correct.
In practice, if the complexity can be accommodated, the first option is superior. Let's look at how this plays out in the case above. There are 4 rounds, each FCC acts as the "king" in one round each:
- FCC-0's own round, it proposes the value from its own sensors:
INCREASE
- FCC-1's own round, it proposes the value from its own sensors:
INCREASE
- FCC-2's own round, it proposes the value from its own sensors:
DECREASE
- FCC-3's own round (faulty), it proposes some value, let's say:
DECREASE
At the end of the 4 rounds, non-faulty FCC-0, 1 and 2 all know that the outcomes of the four rounds was:
INCREASE
INCREASE
DECREASE
DECREASE
They run majority()
on these 4 values, and end up with DECREASE
. So in this case, non-faulty FCC-0, 1 and 2 would all send DECREASE
down the wire to both left and right flaps, which then runs its own majority()
, so irrespective of what the faulty FCC-3 did during the run of the Byzantine Consensus algorithm or what it sends down the wire, both left and right flaps will DECREASE
.
If FCC-3 were to propose INCREASE
in its own round, the non-faulty FCC's majority()
would result in INCREASE
, the three non-faulty FCCs would all send INCREASE
down the wire to both left and right flaps and both would INCREASE
. So faulty FCC-3's behaviour — in case some of the other non-faulty FCCs disagree based on their sensor readings — can still flip the end-result — which is acceptable — but it cannot cause the left and right flaps to receive different commands — as long as $N \geq 3M+1$.
Conclusion
Lamport’s Byzantine Generals algorithm is elegant but narrow: it guarantees agreement among honest nodes in the presence of traitors, but it does not evaluate the quality of the chosen value.
- For distributed databases, the bare algorithm is not enough, since it cannot distinguish between a malicious transaction and a valid one. Modern BFT protocols build additional layers of validity and client authentication on top of the core idea.
- For rocket launch systems, the ability to abort is more important than forcing agreement, so simpler fail-stop or majority mechanisms are preferred.
- For redundant flight computers, however, Byzantine Consensus shines: it prevents subtle divergence between actuators that hardware voters alone cannot fix.
The lesson is that Byzantine Consensus is not a universal tool — but where the system must continue operating, where no abort option exists, and where equivocation can create dangerous asymmetries, it is indispensable.