Two-phase commit is a protocol for making a single transaction succeed or fail atomically across multiple independent nodes. A coordinator asks every participant to prepare the change, waits for all of them to agree, and only then tells everyone to commit. It is one of the oldest solutions to a problem distributed systems still run into: how do you keep a transaction all-or-nothing when data lives on machines that fail independently.
What changed in 2026
- 2PC mostly retreated into infrastructure. Application teams rarely hand-roll it anymore; it now lives inside distributed SQL engines, message brokers with XA support, and database drivers, not in service-to-service application code.
- Saga adoption kept climbing for cross-service writes. As more teams run dozens of independently deployed services, the operational cost of 2PC blocking on a single slow participant pushed most cross-service transaction work toward sagas and outbox patterns instead.
- Timeout and heuristic-recovery tooling matured. Modern 2PC implementations expose better observability into in-doubt transactions, shortening how long a stuck coordinator can hold locks before an operator, or automation, intervenes.
How the two phases work
- Prepare phase. The coordinator sends a "can you commit" request to every participant. Each participant does the work, writes it to a durable log, and replies yes or no, but does not commit yet.
- Commit phase. If every participant said yes, the coordinator sends commit to all of them and they finalize the change. If any participant said no, or timed out, the coordinator sends abort to everyone instead.
The property this buys you is atomicity across nodes: either every participant applies the change or none of them do. What it does not buy you is availability during a failure — that tradeoff is what defines the protocol.
The blocking problem
2PC has one well-known failure mode: if the coordinator crashes after participants have said yes but before it sends the final commit or abort, those participants are stuck. They have already promised to commit, so they cannot unilaterally abort, and they cannot commit without instructions. They sit holding locks on that data until the coordinator recovers or a human intervenes.
This is why 2PC is called a blocking protocol. Three-phase commit attempts to fix this with an extra round trip, but it is rarely used in practice because it still fails under network partitions — a direct illustration of the CAP theorem in action: you cannot get consistency, availability, and partition tolerance all at once.
Two-phase commit vs the alternatives
| Approach |
Consistency model |
Availability during failure |
Best for |
| Two-phase commit |
Strong, atomic across nodes |
Poor — can block on coordinator failure |
Small, trusted node sets you fully control (one DB cluster, XA resources) |
| Saga pattern |
Eventual, via compensation |
Good — no global lock held |
Cross-service transactions spanning independently deployed systems |
| Single-database transaction |
Strong, native ACID |
Good, if the database is available |
Everything lives in one database |
| Three-phase commit |
Strong, non-blocking in most cases |
Better than 2PC, still fails under partitions |
Rare — mostly academic or legacy use today |
When two-phase commit still makes sense
2PC is not obsolete, it is just narrower than it used to be. It still earns its place when every participant is a resource you operate directly, the transaction group is small, and strong atomicity matters more than availability, such as a core ledger move inside a financial system.
Once a transaction crosses an organizational boundary — a payment provider, a partner API, a service owned by another team — 2PC becomes a liability. You cannot force someone else's system to hold a lock open for you. That is exactly the gap the saga pattern was built to fill.
Common mistakes
Using 2PC across microservices "for consistency." This couples services at the transaction level, defeating the point of splitting them up, and turns one slow or down service into a hard block for everyone else.
Ignoring in-doubt transaction monitoring. Every 2PC deployment needs alerting on transactions stuck between prepare and commit. Without it, a coordinator crash silently holds production locks until someone notices timeouts elsewhere.
Assuming 2PC guarantees availability. It guarantees consistency. Availability is explicitly what it gives up during a coordinator failure — plan operational response for that case, do not assume it away.
FAQ
Is two-phase commit still used in 2026?
Yes, but mostly inside infrastructure you do not see — distributed databases, XA-compliant message brokers, and storage engines — rather than hand-written across application services.
What is the difference between two-phase commit and a saga?
2PC holds a lock across all participants until everyone agrees, then commits atomically. A saga uses local commits with compensating actions to undo earlier steps if a later one fails. 2PC is stronger but less available; sagas are more available but eventually consistent.
Does two-phase commit prevent all data loss?
No. It prevents partial commits across participants, assuming the coordinator and participants recover correctly. Coordinator failure between phases can still leave participants blocked, not lost, until recovery completes.
Why do distributed SQL databases still use 2PC internally?
Because inside a single database cluster, the participants are nodes you control on a reliable internal network, which is exactly the environment 2PC handles well. The problems show up when you stretch it across services you do not control.
Where to go next