Skip to main content

Lecture 11: More Paxos — Notes

These are notes from the lecture on April 22, 2026. See also the whiteboard descriptions and the whiteboard PDF.

These materials were drafted by AI based on the live whiteboard PDF and audio transcript from the corresponding lecture and then reviewed and edited by course staff. They may contain errors. Please let us know if you spot any.

Recap: Single-Decree Paxos

Single-decree Paxos is a multi-round, two-phase-per-round protocol for making one consensus decision. There are proposers (who propose values), acceptors (who vote), and learners (who count votes and learn the outcome). Each attempt is tagged with a round number (also called a ballot number), pre-allocated so no two proposers ever use the same one.

The messages have two sets of names: the compact form and the descriptive form.

Compact Descriptive Direction
1a(r) prepare proposer → acceptors
1b(r, summary) prepare response or promise acceptor → proposer
2a(r, v) accept proposer → acceptors
2b(r, v) accept response acceptor → learner

In phase 1 the proposer broadcasts a prepare and collects summaries of what acceptors have already done. In phase 2 the proposer picks a value (constrained by those summaries) and broadcasts an accept; acceptors that can do so send accept responses to the learner. A value is chosen when a majority of acceptors have sent 2b(r, v) for the same r and v.

A typical happy-path run looks like this:

Spacetime diagram of the single-round Paxos happy path. Five vertical process lines labeled left to right: P (proposer), A1, A2, A3 (acceptors), L (learner). Time flows downward. Above a dashed phase divider, P sends 1a(r) to all three acceptors and each replies 1b(r, null) to P. Below the divider, P sends 2a(r, v) to all three acceptors and each forwards 2b(r, v) to L. The right side of the diagram is annotated Phase 1 above the divider and Phase 2 below it.

The Non-Null Summary

Last lecture only handled the easy case: a proposer starts a brand-new round with no prior activity, all summaries are null, and it can propose any value it wants.

Now consider the case where an acceptor has already voted in an earlier round. "Voted" means it sent a 2b message.

Suppose A_3 previously sent 2b(1, v_1). Then when A_3 gets a 1a(2) prepare from proposer P_2, it cannot respond with a null summary, since that would mean it was claiming to have never voted in lower rounds. Instead it reports its highest prior vote: the round number and value from the highest-numbered round smaller than the current round in which it voted.

Small spacetime diagram with five vertical process lines labeled P2, A1, A2, A3, L. A vertical ellipsis near the top of A3 indicates elided earlier history in which A3 voted in round 1. Below the ellipsis, an arrow from A3 to L labeled 2b(1, v1) shows that prior vote. Then P2 sends 1a(2) to A3 (only; A1 and A2 are present on the chart but no other interaction with them is shown). A3 replies 1b(2, (1, v1)) back to P2, since its highest prior vote is v1 in round 1.

So the summary is either:

  • null — "I have never voted in any round smaller than r."
  • (r', v') — "The highest round smaller than r in which I voted was r', and I voted for v'."

With this in hand, the complete proposer rule for phase 2 is:

  • Wait for a majority of 1b responses.
  • If all summaries are null, propose any value.
  • Otherwise, propose the value v' from the summary with the highest round number r'.

One subtlety: can two summaries ever report the same round number with different values? No. Each round number is pre-allocated to exactly one proposer, and that proposer will only ever send one value in phase 2 of that round. So there is no ambiguity when picking the highest round.

Why the Proposer Is Constrained

The proposer is not trying to win an argument. It just needs the system to reach some decision. The algorithm constrains which value it may propose precisely so that it cannot accidentally contradict an earlier decision.

In real-world voting you vote for the candidate you prefer. In Paxos, as was put in lecture, "you vote for the one you have to." If the algorithm says propose v_1, the proposer proposes v_1 — it does not matter whether the proposer "wanted" that value.

Two Scenarios

Both scenarios share the same starting state as above: A_3 has already voted for v_1 in round 1. P_2 then starts round 2 by sending 1a(2) to all acceptors. Each acceptor replies with 1b(2, ...), but the outcome of phase 2 depends on which replies P_2 sees first.

Scenario A: the null majority arrives first

A_1 and A_2's 1b(2, null) replies arrive at P_2 before A_3's. P_2 now has a majority in hand, and every summary in that majority is null, so the algorithm permits P_2 to propose any value. Below, P_2 opts to propose a fresh value v_2.

Spacetime diagram with five vertical process lines: P2, A1, A2, A3, L. Time flows downward. A vertical ellipsis above A3 indicates prior history. A3 sends 2b(1, v1) to L as its prior round-1 vote. Then P2 sends 1a(2) to A1, A2, and A3. A1 and A2 each reply 1b(2, null) to P2. A thick horizontal line spans the diagram indicating that P2 has received its majority of 1b messages, with the annotation majority of nulls, so P2 is free. P2 then sends 2a(2, v2) to all three acceptors, choosing a new value because no summary constrained it. A3 late 1b reply is not depicted.

In this scenario, P_2 receives a majority of 1b messages where all the summaries are null. So P_2 is free to propose any value.

It may seem surprising that A_3 already voted for v_1 in round 1 and yet P_2 is allowed to propose a different value in a later round. Could round 1 still complete and choose v_1? No. To choose v_1 in round 1, there would need to be a majority of acceptors with 2b(1, v_1). That requires at least two out of three. A_3 has one vote; A_1 and A_2 would need to vote too. But both A_1 and A_2 just sent 1b(2, null), which means two things simultaneously:

  1. They never voted in round 1 in the past (null summary).
  2. They promise never to vote in any round smaller than 2 in the future.

So 2b(1, v_1) from A_2 cannot have happened in the past (because they sent a null summary indicating htey never voted) and will not happen in the future (since they promised not to). So there will never be a majority of acceptors who vote in round 1. The remaining acceptors who could still act in round 1 are in the minority, so round 1 can never choose anything. It is safe for P_2 to propose freely.

Scenario B: the non-null summary arrives first

Same setup, but now A_3's reply arrives before A_2's. P_2's phase 1 majority consists of 1b(2, null) from A_1 and 1b(2, (1, v_1)) from A_3. There is a non-null summary. The algorithm says: take the highest round number among all non-null summaries (just round 1 here) and propose that value. So P_2 must propose v_1.

Spacetime diagram with five vertical process lines: P2, A1, A2, A3, L. Time flows downward. A vertical ellipsis above A3 indicates prior history. A3 sends 2b(1, v1) to L as its prior round-1 vote. Then P2 sends 1a(2) to A1, A2, and A3. A1 replies 1b(2, null) to P2, which arrives. A2 sends 1b(2, null) but the arrow ends at a red X, indicating the message was dropped in flight. A3 replies 1b(2, (1, v1)) which arrives at P2 (arriving before A2 would have). A thick horizontal tick on P2 indicates that P2 has received its majority, annotated non-null summary so P2 must propose v1. P2 then sends 2a(2, v1) to all three acceptors, constrained by the summary.

From a global vantage point one could verify that it would actually be safe to propose any value in this scenario too, for the same reasons as scenario A. (A_1 and A_2 both sent 1b messages with null summaries.) But P_2 cannot see the whole picture. It only sees its majority of 1b messages. The rule is conservative: if any non-null summary shows up, follow it.

Failure Scenario: Dropped 2b Messages

Suppose round 1 goes perfectly: P_1 collects a majority of 1b(1, null), sends 2a(1, v_1), and all three acceptors reply with 2b(1, v_1). But all three 2b messages get dropped before reaching the learner. The learner never learns anything.

Is v_1 still chosen? Yes. A value is chosen the moment a majority of acceptors send the 2b messages. The learner not receiving them does not undo that fact.

Single-decree Paxos as described in Lamport's paper has no dedicated retransmission mechanism. Recovery from dropped messages works by starting a fresh round. Any proposer that notices the system has been quiet can start round 2. When it does, the 1b responses will contain non-null summaries (since the acceptors voted in round 1), and the algorithm will constrain the proposer to propose v_1 again. The learner then gets 2b(2, v_1) messages, collects a majority, and learns the outcome.

Spacetime diagram with six process lines P1, P2, A1, A2, A3, L. Time flows downward; a horizontal round divider separates round 1 (above) from round 2 (below). Round 1, driven by P1: P1 sends 1a(1) to A1, A2, A3. A1 and A2 each reply 1b(1, null) to P1. P1 sends 2a(1, v1) to A1, A2, A3. All three acceptors send 2b(1, v1) toward L, but each of those arrows ends in a red X before reaching L, indicating the messages were dropped. Round 2, driven by P2: P2 sends 1a(2) to A1, A2, A3. A1 and A2 each reply 1b(2, (1, v1)) to P2, reporting the prior vote for v1. P2 sends 2a(2, v1) to the acceptors. An acceptor sends 2b(2, v1) to L, which successfully arrives.

The same value gets chosen a second time. That is fine: the correctness guarantee is that no different value ever gets chosen, not that the same value can only be chosen once. In practice you add retransmission as a performance optimization, and the learner signals everyone to stop once it has a result. But the algorithm is correct without those additions.

The Votes Table

A useful visualization for understanding Paxos: draw a table with acceptors as columns and rounds as rows. Each cell records what that acceptor did in that round:

  • (check) — the acceptor voted (sent 2b) in that round.
  • (X) — the acceptor promised not to vote in that round (sent 1b in a higher round, locking out this one). An X is not a "no vote" — there is no such thing as voting no in Paxos. X means "will never vote here."
  • empty — neither voted nor promised not to vote (the default).

A value is chosen exactly when some row has a majority of check marks.

Here is the table for the two-round scenario where round 1 got a minority vote and round 2 completes:

A grid diagram with columns labeled A1, A2, A3 (acceptors) and two rows labeled 1, v1 and 2, v2. Row (1, v1): A1 has an X, A2 has an X, A3 has a check. Row (2, v2): A1 is empty, A2 has a check, A3 has a check.

The X entries are what enforce safety. When P_2 collects a majority of 1b(2, ...) from A_1 and A_2, those two acceptors each get an X in row 1. Now row 1 has a majority of Xs, which means it can never accumulate a majority of check marks. Round 1 is dead.

The table also makes clear that the same acceptor can vote in multiple rows with different values. That is not a contradiction. It only becomes a problem if two different rows each have a majority of check marks, which the algorithm prevents.

Why Any Two Majorities Overlap

The key mathematical fact underlying all of this: any two majorities of the same set of acceptors share at least one element.

If you have n acceptors and two subsets each of size greater than n/2, they cannot be disjoint (they would need more than n elements total). So they share at least one acceptor.

This is why the 1b mechanism works. When P_2 collects a majority of prepare responses, that majority is guaranteed to overlap with any previous majority that voted in phase 2. The overlapping acceptor reports its vote in its summary, and the algorithm is constrained to carry that value forward.

Three-Round Scenario

One more scenario. Suppose A_3 voted for v_1 in round 1, and A_2 voted for v_2 in round 2. Both of these are 2b votes. What values can be proposed in round 3?

Diagram with four vertical process lines labeled A1, A2, A3 (acceptors) and L (learner) on the right. Small vertical ellipses appear above A2 and A3 to indicate prior activity. Three rightward arrows head to L, stacked top to bottom: 2b(1, v1) from A3 to L; 2b(2, v2) from A2 to L; 2b(3, {v1, v2}) from A1 to L, indicating the round 3 vote carries whichever of v1 or v2 the proposer was forced to propose.

The answer depends on which acceptors respond to the phase 1 prepare for round 3. With only three acceptors, a majority is two. Every pair of two acceptors includes at least one of A_2 or A_3, both of whom have prior votes. There is no pair of acceptors who have both never voted. So P_3 cannot get a null-only majority. It will always see at least one non-null summary, and it must propose whichever of v_1 or v_2 comes from the highest round number among the summaries it receives.

With five acceptors the situation is different: two acceptors could vote in round 1 and round 2 respectively, leaving three who have never voted. A later proposer could collect three null summaries and propose freely. So the interaction between the number of acceptors and the number of rounds matters.

What's Next

Next lecture will introduce MultiPaxos, which strings single-decree instances together to fill slots in a replicated log.