Two-Phase Commit
A protocol ensuring all nodes in a distributed transaction either commit or abort together. Phase 1: prepare (vote). Phase 2: commit or rollback.
What is Two-Phase Commit?
In short
Two-Phase Commit (2PC) is a protocol that makes several databases or services agree on whether to commit or roll back a single distributed transaction, so they all end up in the same state. A coordinator first asks every participant to prepare and vote, then tells them all to commit only if every vote was yes, otherwise it tells them all to abort.
What it is
When one transaction touches data on more than one machine, you have a problem: each machine can commit or roll back on its own, but you need them to act as a unit. If the order service saves a row but the inventory service crashes before it saves, you have charged a customer for stock you never reserved. Two-Phase Commit is the classic protocol that prevents that split outcome.
There are two roles. A coordinator (sometimes called the transaction manager) drives the protocol. The participants (the resource managers, usually databases) each hold one piece of the transaction. The whole point is atomicity across all of them: either every participant commits, or every participant aborts, and nobody is allowed to be left half done.
2PC gives you atomic commit but it is not the same as consensus protocols like Paxos or Raft. Those keep working when a node fails. 2PC, in its basic form, can get stuck if the coordinator dies at the wrong moment, which is its biggest weakness.
How it works under the hood
Phase one is prepare. The coordinator sends a PREPARE message to every participant. Each participant does all the work it can without finalizing: it writes the changes to its log, takes locks, and makes sure it could commit if asked. It then writes a prepare record to durable storage and replies YES (also called a vote to commit) or NO. Once a participant has voted YES it is in a prepared state and has promised it can commit even if it crashes and restarts, so it must keep its locks held.
Phase two is the decision. If every participant voted YES, the coordinator writes a commit record to its own log, then sends COMMIT to everyone. If even one voted NO, or one timed out, the coordinator writes an abort record and sends ABORT. Each participant carries out the order, releases its locks, and sends back an acknowledgement. The coordinator's log write is the single point where the outcome becomes final.
The danger window is the prepared state. A participant that has voted YES cannot decide on its own. If the coordinator crashes after collecting votes but before sending the decision, the participant is blocked. It holds its locks and waits, because committing or aborting unilaterally could disagree with what the coordinator already logged. This is why 2PC is called a blocking protocol.
When to use it and the trade-offs
Use 2PC when you genuinely need atomic commit across separate systems and the systems are usually healthy, low latency, and within your control. Distributed SQL databases, the XA standard used by Java application servers and message brokers, and some transactional file systems all rely on it. It is correct and well understood, which is why it has survived for decades.
The costs are real. Every commit needs at least two network round trips plus several forced disk writes, so latency goes up and throughput goes down. Locks are held from prepare until the decision arrives, so a slow participant stalls everyone and reduces concurrency. And the blocking problem means a coordinator failure can freeze a transaction until an operator or a recovery process steps in. Three-Phase Commit adds an extra round to reduce blocking, but it assumes bounded network delays and is rarely used in practice.
For this reason many modern systems avoid 2PC across service boundaries. Instead they use the Saga pattern, which breaks the work into local transactions with compensating actions that undo earlier steps, trading strict atomicity for availability. A good rule: keep 2PC inside one tightly coupled cluster, and reach for Sagas when services are independent and failures are common.
A concrete example
Imagine a bank transfer of 100 dollars where the source account lives in shard A and the destination in shard B. The coordinator sends PREPARE to both shards. Shard A checks the balance, deducts 100 in its log, locks the row, and votes YES. Shard B logs the 100 credit, locks its row, and votes YES.
Both votes are in, so the coordinator writes COMMIT to its log and tells both shards to commit. Money leaves A and lands in B atomically. If instead shard A had reported insufficient funds and voted NO, the coordinator would have written ABORT, and shard B would have rolled back its prepared credit so no money appears out of nowhere.
Now suppose the coordinator crashes right after both shards voted YES but before it sent the decision. Both shards sit in the prepared state with rows locked, unable to commit or abort, until the coordinator restarts, reads its log, sees no commit record, and replays the protocol to a safe conclusion. That stuck interval is exactly the blocking behavior 2PC is famous for.
Where it is used in production
MySQL XA / Java application servers
Implement the XA standard, a 2PC interface that lets one transaction span a database and a message queue.
Google Spanner
Uses 2PC layered on top of Paxos groups so the coordinator itself is replicated, removing the single-coordinator blocking risk.
PostgreSQL
Exposes PREPARE TRANSACTION and COMMIT PREPARED so an external coordinator can run 2PC across multiple Postgres instances.
Apache Kafka
Its transactional producer uses a 2PC-style protocol between the producer and broker transaction coordinator to commit messages across partitions atomically.
Frequently asked questions
- What are the two phases in two-phase commit?
- Phase one is prepare: the coordinator asks every participant to do all the work, lock its data, and vote YES or NO. Phase two is the decision: if all voted YES the coordinator orders a commit, and if anyone voted NO or timed out it orders an abort. The decision is final once the coordinator writes it to its own log.
- Why is two-phase commit called a blocking protocol?
- Once a participant votes YES it enters a prepared state, holding locks and waiting for the coordinator's decision. If the coordinator crashes after collecting votes but before sending the outcome, the participant cannot safely decide alone, so it stays blocked with locks held until the coordinator recovers.
- How is two-phase commit different from a Saga?
- 2PC gives strict atomicity by holding locks and committing all participants together, which blocks under failure. A Saga runs a sequence of independent local transactions and uses compensating actions to undo earlier steps if a later one fails, trading strict atomicity for higher availability and looser coupling between services.
- Does two-phase commit guarantee the database stays consistent if the network fails?
- It guarantees atomicity, meaning all participants reach the same commit-or-abort outcome, so you never get a half-applied transaction. It does not guarantee availability: a network partition or coordinator crash can leave prepared participants blocked with locks held until communication is restored.
- How does three-phase commit improve on two-phase commit?
- Three-Phase Commit inserts an extra pre-commit round so participants learn the decision is coming before they must finalize, which lets them recover without indefinitely blocking if the coordinator dies. It only works under the assumption of bounded network delays and no message loss, so it is rarely used in real systems.
Learn Two-Phase Commit hands-on
This page explains the idea. The full lesson lets you step through the ring as servers join and leave, read the implementation, and check yourself with a quiz. It is one of 760+ lessons in the System Design Masterclass, from your first API call to distributed consensus. Eleven Foundation lessons are free, no signup. Lifetime access is ₹499 in India or $7.99 worldwide, one payment, no subscription.
See also
Related glossary terms you might want to look up next.
ACID
Four guarantees for database transactions: Atomicity (all or nothing), Consistency (valid states only), Isolation (no interference), Durability (changes persist).
Saga Pattern
A way to manage distributed transactions across microservices using a sequence of local transactions with compensating actions for rollback.
Consensus
The process of getting multiple nodes in a distributed system to agree on a single value. The foundation of distributed databases and coordination services.
CAP Theorem
In a distributed system, you can only guarantee two of three: Consistency, Availability, and Partition tolerance. You must choose your trade-off.
Paxos
A family of protocols for solving consensus in unreliable networks. Famously difficult to understand but mathematically proven correct.
Raft
A consensus algorithm designed to be understandable. Uses leader election and log replication. Powers etcd (used by Kubernetes) and CockroachDB.