MongoDB Transactions
Parent: MongoDB Expert Knowledge · Published reference · snapshot 2026-09-08 · skill mongodb-expert/references/mongodb-transactions.md
↓ Facts as markdownall context files
---
These notes link each claim to its source. Some citations identify archived research reports that are no longer hosted on this site. A published reference means the content is available; it does not certify independent review or accuracy.Read the editorial policy and follow the sources before relying on a claim.
1. Multi-Document Transactions Overview
- MongoDB added multi-document ACID transactions in 4.0 (replica sets) and extended them to sharded clusters in 4.2. Before 4.0, atomicity was limited to single-document operations (which remain the preferred approach for most use cases). [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#1-multi-document-transactions-overview]
- ACID guarantees provided: [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#1-multi-document-transactions-overview]
- Atomicity - all writes in the transaction commit together or all are rolled back [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#1-multi-document-transactions-overview]
- Consistency - data is moved from one valid state to another; session-level causal consistency is maintained [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#1-multi-document-transactions-overview]
- Isolation - snapshot isolation: the transaction sees a consistent snapshot of data as of the transaction start; no dirty reads, no non-repeatable reads [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#1-multi-document-transactions-overview]
- Durability - committed data survives node failures when w: "majority" is used [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#1-multi-document-transactions-overview]
- Snapshot isolation is the default isolation level since 4.0. Within a transaction, a client sees the data as it existed at transaction start, even if concurrent writers commit changes. This avoids dirty reads and non-repeatable reads but can cause write conflicts (two transactions modifying the same document - the second writer's commit or a read-write conflict will abort one of them). [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#1-multi-document-transactions-overview]
2. Replica Set Transactions
- All primary-based writes in a replica set transaction are routed to the primary. The session object carries the transaction state. [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#2-replica-set-transactions]
withTransaction() callback API (recommended)
- withTransaction() handles commit retry and transient error retry automatically. Prefer this over the manual try/catch pattern. Available since Node.js driver 3.2+ and PyMongo 3.9+. [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#withtransaction-callback-api-recommended]
3. Distributed Transactions on Sharded Clusters
- Since MongoDB 4.2, multi-document transactions work across shards using two-phase commit (2PC). [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#3-distributed-transactions-on-sharded-clusters]
Two-Phase Commit coordinator
- When a transaction touches multiple shards, the mongos router designates one of the participant shards as the coordinator (the shard that receives the first write). The coordinator: [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#two-phase-commit-coordinator]
- Prepare phase - sends prepareTransaction to all participant shards; each shard locks its data and votes yes/no [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#two-phase-commit-coordinator]
- Commit phase - if all shards vote yes, coordinator sends commitTransaction to all; if any vote no, sends abortTransaction [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#two-phase-commit-coordinator]
- The coordinator's decision is durable in config.transactions so recovery is possible after coordinator failure. [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#two-phase-commit-coordinator]
- Performance cost vs. replica set transactions: [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#two-phase-commit-coordinator]
- 2PC adds at least one extra round-trip (prepare → commit) per participating shard [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#two-phase-commit-coordinator]
- Each shard holds WiredTiger write locks during the prepare phase [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#two-phase-commit-coordinator]
- Cross-shard transactions are 2–4× slower than replica set transactions under load [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#two-phase-commit-coordinator]
- Prefer co-locating transactional data on the same shard (zone sharding, compound shard keys) to avoid cross-shard transactions [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#two-phase-commit-coordinator]
4. Read Concern in Transactions
- The read concern set on startTransaction() applies to all reads within the transaction. [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#4-read-concern-in-transactions]
- Snapshot isolation detail: [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#4-read-concern-in-transactions]
- MongoDB picks a clusterTime at transaction start as the snapshot point [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#4-read-concern-in-transactions]
- Reads within the transaction consistently see the state as of that clusterTime [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#4-read-concern-in-transactions]
- If the snapshot falls behind the oldest in-use WiredTiger snapshot, MongoDB will abort the transaction with SnapshotTooOld (increase wiredTigerCacheSizeGB or reduce long-running transactions) [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#4-read-concern-in-transactions]
5. Write Concern in Transactions
- Write concern on a transaction applies at commit time - it controls how many replica set members must acknowledge the commit before the driver considers it successful. [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#5-write-concern-in-transactions]
- Write concern levels: [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#5-write-concern-in-transactions]
- j: true (journaled): [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#5-write-concern-in-transactions]
- Ensures the commit is written to the on-disk journal before returning success [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#5-write-concern-in-transactions]
- Protects against data loss from process crash (but not disk failure) [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#5-write-concern-in-transactions]
- Adds latency; omit only if you can tolerate potential data loss [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#5-write-concern-in-transactions]
- If the majority acknowledgment isn't received within wtimeout milliseconds, the server returns a WriteConcernError (code 64 / wtimeout) [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#5-write-concern-in-transactions]
- The driver wraps this as an error with the UnknownTransactionCommitResult label - the transaction may still have committed on the primary; the outcome is uncertain [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#5-write-concern-in-transactions]
- Correct action: retry the commit only (not the full transaction body); withTransaction() does this automatically [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#5-write-concern-in-transactions]
Operation count
- No fixed cap on the number of operations (reads + writes) per transaction; the practical limit is oplog size and WiredTiger cache pressure (see below). (A "1,000 per transaction" figure sometimes cited is the driver bulk-write batch-group size, not a transaction limit.) [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#operation-count]
Oplog entry size
- MongoDB 4.2 and earlier: each transaction generates a single oplog entry capped at 16 MB [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#oplog-entry-size]
- MongoDB 4.4+: large transactions are broken into a chain of applyOps oplog entries, effectively unlimited in size (bounded only by available oplog space and WiredTiger cache) [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#oplog-entry-size]
Transaction lifetime
- Transactions exceeding transactionLifetimeLimitSeconds are automatically aborted by the server [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#transaction-lifetime]
- Long-running transactions hold WiredTiger cache and delay checkpoint - keep transactions short [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#transaction-lifetime]
WiredTiger cache pressure
- Active transactions pin the oldest required snapshot in the WiredTiger cache [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#wiredtiger-cache-pressure]
- If cache pressure exceeds 95% utilization, MongoDB aborts the oldest transaction (WriteConflict or TemporarilyUnavailable) [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#wiredtiger-cache-pressure]
7. Retryable Transactions
- MongoDB drivers classify transaction errors into two categories that require different retry strategies. [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#7-retryable-transactions]
Automatic retry via withTransaction()
- withTransaction() handles both TransientTransactionError (retries the callback) and UnknownTransactionCommitResult (retries commit) automatically. This is the recommended production pattern. [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#automatic-retry-via-withtransaction]
Overhead measurement
- Compared to a non-transactional equivalent write, a 2-operation replica set transaction adds: [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#overhead-measurement]
- ~1–2 ms coordinator overhead on a local cluster [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#overhead-measurement]
- ~5–15 ms additional latency on a cross-datacenter replica set (round-trip for majority ack) [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#overhead-measurement]
- ~2–4× slower throughput under high concurrency due to write-conflict aborts [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#overhead-measurement]
Write conflict storms
- When many concurrent transactions attempt to modify the same document, MongoDB aborts all but the first writer, forcing retries. This is "hot document" contention. [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#write-conflict-storms]
- Redesign schema to avoid hot documents (counters, queue heads) [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#write-conflict-storms]
- Use $inc on a field that's rarely contended vs. an array that many writers append to [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#write-conflict-storms]
- Rate-limit transactional writers at the application layer [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#write-conflict-storms]
References
- https://www.mongodb.com/docs/manual/core/transactions/ [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#references]
- https://www.mongodb.com/docs/manual/core/transactions-in-applications/ [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#references]
- https://www.mongodb.com/docs/manual/core/transactions-production-consideration/ [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#references]
- https://www.mongodb.com/docs/manual/reference/method/Session.startTransaction/ [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#references]
- https://www.mongodb.com/docs/drivers/node/current/fundamentals/transactions/ [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#references]
- https://www.mongodb.com/docs/manual/core/read-isolation-consistency-recency/ [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-transactions/#references]
Where this helps
- Multi-document invariants that must move together, such as a funds transfer that debits one account and credits another, or an order-plus-inventory-decrement, where single-document atomicity isn't enough. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
- Workflows that need snapshot isolation across several reads and writes within one logical operation, so concurrent writers can't produce a torn read. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
- Sharded-cluster operations that must span documents living on different shards, accepting the 2-4x cost of two-phase commit in exchange for cross-shard atomicity. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
- Migrations or backfills that must apply a batch of related writes atomically, using withTransaction() so transient errors and commit-result-unknown cases retry safely instead of leaving partial state. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
Project ideas
- Build a funds-transfer or ledger-adjustment service using withTransaction() so debit/credit pairs commit or roll back together, with w: majority and j: true on the commit write concern. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
- Build a retry-safe batch-update job that lets withTransaction() handle both TransientTransactionError and UnknownTransactionCommitResult automatically instead of hand-rolling retry logic. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
- Build a load test that measures transaction overhead on your own cluster, comparing a 2-operation transactional write against the non-transactional equivalent to see the real coordinator and cross-datacenter latency cost. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
- Build a hot-document mitigation for a queue-head or counter pattern, replacing an array many writers append to with a rarely-contended $inc field, then measure the drop in write-conflict aborts. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
Antipatterns
- Using multi-document transactions as the default write pattern instead of reaching for single-document atomicity first: transactions add real latency (coordinator round-trips, cross-shard 2PC) that most writes don't need. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
- Hand-rolling commit retry logic instead of using withTransaction(): manual try/catch loops are easy to get wrong around the TransientTransactionError vs UnknownTransactionCommitResult distinction, where the commit may have actually succeeded. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
- Letting many concurrent transactions target the same hot document, such as a shared counter or queue head: MongoDB aborts all but the first writer, so contention shows up as a wave of forced retries rather than a slow query. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
- Designing a workload that routinely needs multi-shard transactions instead of co-locating transactional data on one shard via zone sharding or compound shard keys: cross-shard transactions run 2-4x slower than replica-set transactions. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
Known issues
- Long-running transactions pin the oldest required snapshot in the WiredTiger cache; if cache pressure exceeds roughly 95% utilization, MongoDB aborts the oldest transaction rather than the newest. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
- A transaction can abort with SnapshotTooOld if its snapshot falls behind the oldest in-use WiredTiger snapshot, mitigated by increasing wiredTigerCacheSizeGB or keeping transactions short. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
- Transactions exceeding transactionLifetimeLimitSeconds are aborted automatically by the server, so long-running application logic inside a transaction body is a reliability risk, not just a performance one. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
- A WriteConcernError carrying the UnknownTransactionCommitResult label means the transaction may have actually committed on the primary; the correct recovery is to retry only the commit, never the full transaction body. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
Children
- Multi-Document Transactions (frontier)
- Replica Set Transactions (frontier)
- Distributed Sharded Transactions (frontier)
- Read Concern (frontier)
- Write Concern (frontier)
- Transaction Limits (frontier)
- Retryable Transactions (frontier)
- Driver Examples (frontier)
- Performance Impact (frontier)
- Transaction Anti-Patterns (frontier)
Frontier under this node: Distributed Sharded Transactions, Driver Examples, Multi-Document Transactions, Performance Impact, Replica Set Transactions, Retryable Transactions, Transaction Anti-Patterns, Transaction Limits