Every atomic commit protocol can block; they differ in when

A distributed transaction has to commit everywhere or nowhere: the atomic commit problem. Any participant may need to abort, say because a constraint fails, so each participant votes first. Voting Prepared means "I can commit, and I will if told to." From then on the participant can't act alone: it doesn't know the other votes, so committing could override someone's Aborted, and aborting could contradict a commit already made on its Prepared. It must wait for the outcome, and committing needs every vote. So the question every commit protocol must answer is what happens when a vote goes missing.

The simplest design has no coordinator: participants exchange votes and each counts. Counting works when every vote arrives. Say A and B vote Prepared and receive each other's votes, but C's vote hasn't reached B. B can't tell two runs apart: in one, C crashed before voting; in the other, C voted Prepared and the message is slow. B has two choices, and each fails in one of the runs. If B waits, then in the first run it waits forever: the protocol never finishes, a liveness failure. If B gives up and aborts, then in the second run A has already received C's Prepared and committed: A commits, B aborts, a safety failure. Both runs look the same to B, so no rule based on what B sees avoids both. That dilemma is the intuition behind the FLP result: in an asynchronous system where even one process can crash, no deterministic consensus protocol guarantees both safety and termination [1].

Two runs B can't tell apartTwo runs on three lanes, A, C and B, with time running left to right. In both, A and B first swap their Prepared votes. In run 1, C crashes before voting; A and B time out and abort. In run 2, C votes Prepared; the message reaches A before its timeout, so A commits, but reaches B after its timeout, so B aborts. B's lane looks the same in both runs up to its timeout.Run 1 · C crashedACBtimeoutabortsabortsRun 2 · C's vote is slowACBcommitsaborts
B's view, shaded, is the same in both runs, so B acts the same, and in run 2 that splits it from A. Thin arrows are A's and B's Prepared votes, thick ones C's; each commits only if all three votes arrive before its timeout.

For a commit, giving up safety isn't an option: everyone ending in the same state is the whole job. So a commit protocol keeps safety and pays in liveness, and the only question is when it blocks.

What keeps it safe? A and B split because each settled C's vote from its own view. Settle it once instead, in one record, and have every participant read the outcome from that record rather than its own count, and they can't disagree: they're all reading the same answer. Which answer, Prepared or Aborted, matters less than that there is only one.

Two-phase commit keeps that record on one machine. A coordinator collects the votes, decides commit only if all are Prepared, writes the decision to its log and tells everyone. That single log is why it blocks [2]. If the coordinator fails after every participant has voted Prepared and none has heard the decision, none can tell whether the transaction committed or aborted: the coordinator may have received every vote and committed, or timed out on a slow one and aborted, and only its log says which. They stay stuck in the prepared state until it comes back.

Two-phase commit keeps the record on one machineParticipants A, B and C each send Prepared to one coordinator, whose log holds the decision. The coordinator has failed, so the decision is unknown and all three wait.Two-phase commitone record on one machineA: PreparedB: PreparedC: Preparedcoordinatorlog:decision ?down
Two-phase commit keeps the record in one coordinator's log. When the coordinator fails, A, B and C can't learn the decision, so they wait.

The obvious fix is to run consensus on the coordinator's decision among a few machines, called acceptors, so a majority holds it and no single crash can hide it. That survives any single crash, but it lengthens the path: each vote travels participant → coordinator → acceptors, because the coordinator has to collect every vote before it can propose commit.

Look at what the coordinator actually decides: commit if every vote is Prepared, otherwise abort. That is a fixed rule over the votes. Once the votes themselves are safely recorded, nobody needs to decide anything; anyone can compute the outcome. So Paxos Commit replicates the inputs instead of the output: the votes, not the decision [3]. And since no one has to gather the votes to compute a decision, each vote can go straight to the acceptors instead of through the coordinator. That removes the extra hop: in the normal case Paxos Commit can match 2PC's latency, at the cost of more messages.

Concretely, the record is a small table with one slot per participant: A's vote, B's vote, C's vote. It lives on the acceptors, and consensus settles each slot separately, so each participant can write its own vote without waiting for anyone else. A slot's value survives as long as a majority of the acceptors do, so three acceptors survive one failure.

Paxos Commit keeps one slot per vote on a majorityThree acceptors each hold a slot for A, B and C. A's and B's slots hold Prepared. Acceptor 3 is down. C's vote went missing, and the leader's Aborted was accepted by the other two acceptors, a majority, so C's slot is Aborted and every participant reads abort.Paxos Commitone slot per vote, settled by a majorityA's slotB's slotC's slotacceptor 1PreparedPreparedAbortedacceptor 2PreparedPreparedAbortedacceptor 3: downPreparedPrepared—
Paxos Commit gives each vote a slot settled by a majority of acceptors. With acceptor 3 down, the leader's Aborted for C still holds on a majority, so everyone reads abort.

Committing needs every vote, though, and a participant can stay silent. Someone has to give up on it. That job goes to the leader, all that remains of the coordinator. If C's slot is still empty when the leader's timer runs out, the leader proposes Aborted for it. What consensus guarantees is that each slot settles on exactly one value, and that a settled value never changes: if C's Prepared settled first, the slot keeps it. The leader can only fill C's slot, never decide the outcome. The figure's C column shows Aborted winning, held by a majority even with acceptor 3 down.

So B still can't tell whether C is slow or dead, but it no longer has to: it reads C's slot instead of deciding from what it saw. The transaction commits if every slot holds Prepared and aborts otherwise. Paxos Commit can stall only when there is no stable leader or no majority of acceptors up, as FLP says some run must, but no two participants ever read different values.

Unlike 2PC's coordinator, the leader holds nothing the acceptors don't, so losing it costs time, not knowledge. With a single acceptor the protocol reduces to 2PC, with the coordinator as that acceptor, and "no majority of acceptors up" becomes "the coordinator is down."

References

  1. Impossibility of Distributed Consensus with One Faulty Process
    Fischer, M. J., Lynch, N. A. and Paterson, M. S., 1985. Journal of the ACM, Vol 32(2), pp. 374–382. DOI: 10.1145/3149.214121

  2. Designing Data-Intensive Applications
    Kleppmann, M. and Riccomini, C., 2026. O'Reilly Media.

  3. Consensus on Transaction Commit [link]
    Gray, J. and Lamport, L., 2004. arXiv. DOI: 10.48550/ARXIV.CS/0408036