Modern MongoDB applications can have thousands of clients reading and modifying data concurrently. For a DBA, the important question is not simply how MongoDB stores documents, but how it allows these operations to run concurrently while maintaining consistency.
A key part of the answer is WiredTiger, MongoDB’s default storage engine, which uses Multi-Version Concurrency Control (MVCC) along with locking and transaction mechanisms.
Understanding this at a practical level helps DBAs diagnose issues such as write conflicts, hot documents, long-running transactions, and increasing operation latency.
This blog focuses on the DBA perspective: how WiredTiger’s concurrency model affects production behavior and what to look for when troubleshooting it.
Why MongoDB Concurrency Matters
Consider a collection where multiple clients are working at the same time:
Client A → Customer 101 → Update
Client B → Customer 102 → Update
Client C → Customer 103 → Read
Client D → Customer 104 → Update
These operations are largely independent. Ideally, an update to Customer 101 should not unnecessarily prevent another client from reading Customer 103.
MongoDB provides document-level concurrency control through WiredTiger, while MongoDB’s lock manager also uses multi-granularity locks at higher resource levels.
The result is not “one traditional lock per document.” Instead, multiple concurrency mechanisms work together.
Fine-grained concurrency can improve throughput when the workload contains sufficiently independent operations, but it is not a guarantee of higher throughput. CPU, I/O, indexes, cache pressure, transaction workload, and contention can all become limiting factors.
For a DBA, this distinction matters when deciding whether a concurrency problem is caused by the database engine, the workload, or the data model.
How WiredTiger MVCC Helps With Concurrency
MVCC, or Multi-Version Concurrency Control, allows transactions to work with transactionally appropriate versions of data rather than requiring every reader to wait for every writer.
A useful conceptual model is:
Older state
|
v
Newer state
|
v
Current state
This is a conceptual model only. It should not be interpreted as a representation of WiredTiger’s physical storage layout or as a literal chain of documents stored on disk.
The important idea is that data visibility is associated with transaction state and visibility rules. This allows concurrent operations to work with data without relying solely on blocking locks.
MongoDB still uses locks. MVCC does not replace locking; the two mechanisms address different aspects of concurrency.
For a DBA, the benefit is that independent reads and writes can coexist efficiently instead of being unnecessarily serialized.
What Happens When Two Writes Conflict?
Concurrency becomes more interesting when two operations target overlapping data.
For example:
db.accounts.updateOne( { _id: 1001 }, { $inc: { balance: -100 } })
If another operation concurrently attempts a conflicting modification to the same document, WiredTiger can detect a write conflict.
One important distinction is often missed in DBA discussions:
A WiredTiger write conflict is not the same as waiting for a MongoDB lock.
A write conflict occurs when concurrent operations cannot both proceed with their modifications as attempted.
These concepts should be kept separate:
- WiredTiger write conflict — a storage-engine concurrency conflict.
- MongoDB/internal retry — MongoDB may retry certain write-conflict situations internally.
- Transaction retry — a driver or application may need to retry a transaction when MongoDB reports a transient transaction error.
- Retryable writes — driver/application retry behavior for supported retryable write operations.
Therefore, seeing a write conflict does not automatically mean that the application performed a retry.
If write conflicts increase significantly, the DBA should investigate the workload rather than immediately treating the issue as lock contention.
Look for:
- Multiple writers targeting the same documents
- Changes in application traffic
- Hot documents
- Longer transaction lifetimes
- Changes in application retry behavior
The goal is to determine why operations are competing, not simply count the conflicts.
Hot Documents: Where Concurrency Becomes Contention
Document-level concurrency control works best when operations are distributed across independent documents.
Consider a shared counter:
{ _id: "global_counter", value: 98453276}
Suppose thousands of requests execute:
db.counters.updateOne( { _id: "global_counter" }, { $inc: { value: 1 } })
The $inc operation is atomic and efficient for a single-document update, but concentrating a very high write rate on one document can still create contention.
Conceptually:
Client 1 ──┐
Client 2 ──┤
Client 3 ──┼──> global_counter
Client 4 ──┤
Client 5 ──┘
This creates a hot document and potentially significant write contention.
This is an important production lesson:
Document-level concurrency control does not mean unlimited concurrent modification of the same document.
If the workload is concentrated on a small number of documents, adding more application threads may increase contention rather than improve throughput.
For a DBA, the investigation should therefore include the data access pattern. If a particular document is receiving an unusually high write rate, the long-term solution may involve schema or application changes rather than a MongoDB configuration change.
Single-Document Atomicity vs. Multi-Document Transactions
Another important distinction is atomicity.
MongoDB operations on a single document are atomic; multi-document transactions are needed when atomicity must span multiple documents or collections.
For example:
db.accounts.updateOne( { _id: 1001 }, { $inc: { balance: -100 } })
is atomic at the single-document level.
If a business operation requires coordinated changes to multiple documents, a transaction may be appropriate:
Transaction
|
+–> Update Account A
|
+–> Update Account B
|
+–> Commit / Abort
Transactions provide useful guarantees, but they also introduce additional coordination and resource considerations.
For DBAs, the important question is not simply whether a transaction can be used, but whether the business operation actually requires atomicity across multiple documents or collections.
Why Long-Running Transactions Matter
Transaction duration is another important production consideration.
A transaction should be thought of simply as:
Transaction starts
|
v
Reads / Writes
|
v
Transaction remains open
|
v
Commit / Abort
This diagram describes transaction lifetime—not data visibility.
The exact visibility guarantees depend on the operation, transaction context, and configured read concern.
Long-running transactions or snapshots can require historical data to remain available for longer, potentially increasing history and cache pressure.
They can also extend the period during which a transaction overlaps with concurrent operations.
However, a long-running transaction does not automatically cause write conflicts. A conflict depends on whether concurrent operations overlap the relevant data and access patterns.
For a DBA, transaction duration should therefore be monitored alongside workload contention rather than treated as a direct indicator of conflicts.
A practical rule remains:
Keep transactions as short as the application requirements allow.
Avoid keeping a transaction open while performing unnecessary application processing, external API calls, or other work unrelated to the database transaction.
What should we monitor?
Concurrency troubleshooting should combine MongoDB metrics with workload analysis.
MongoDB monitoring details can change between releases, so the exact fields and behavior should always be verified against the MongoDB version deployed in the environment.
Current Operations
MongoDB provides the $currentOp aggregation stage for inspecting current operations. The db.currentOp() helper provides an interface for current-operation information and is still commonly encountered in DBA scripts.
When investigating concurrency, look at information such as:
- Operation duration
- Whether an operation is active or waiting
- Transaction-related information
- Operation type and namespace
- Lock-related information where applicable
For versions and operation types that expose it, the writeConflicts field can also provide useful information about write-conflict activity.
The important diagnostic question is:
Is the operation actually waiting, actively consuming resources, participating in a transaction, or encountering contention?
This helps prevent a DBA from incorrectly labeling every slow operation as a locking problem.
Transaction Activity
Transaction statistics are available through:
db.serverStatus().transactions
Rather than looking at the entire statistics object, focus on useful indicators such as:
- currentActive — transactions currently active.
- currentOpen — transactions currently open.
- currentInactive — transactions that remain open but are currently inactive.
- totalCommitted — cumulative committed transactions.
- totalAborted — cumulative aborted transactions.
The value comes from observing these metrics over time.
For example, a rise in currentOpen or currentInactive during an application slowdown can prompt investigation into transaction duration and application behavior. An increase in totalAborted may indicate transaction failures or workload issues that require further investigation.
The metrics should always be interpreted against the MongoDB version and workload rather than treated as standalone indicators of a problem.
Write Conflicts
When available through the relevant MongoDB monitoring interfaces, writeConflicts should be interpreted as a count of conflict events, not as a count of conflicting documents.
For example, 10,000 write conflicts does not necessarily mean that 10,000 different documents were involved.
A DBA should compare the conflict count with workload volume, operation rates, latency, and transaction activity.
The useful question is:
Are write conflicts increasing relative to the amount of write activity?
A rising conflict rate alongside increased latency may indicate increasing contention, especially if the workload is concentrated on a small set of documents.
Execution and Concurrency Pressure
Execution queue information can also help identify whether operations are waiting for available execution resources.
Where the relevant execution queue metrics are available for the deployed MongoDB version, monitor queue depth and the relationship between queued and active work.
An increasing queue combined with high CPU utilization can point toward execution-resource saturation rather than a storage-engine write conflict.
This distinction is important because not every queue or latency problem is a locking problem.
WiredTiger Statistics
WiredTiger statistics can be inspected through:
db.serverStatus().wiredTiger
Rather than treating this as one overall “concurrency” metric, use the relevant sections to investigate the symptom—for example, cache behavior, transaction activity, history-related pressure, and storage-engine activity.
A DBA should correlate these observations with:
Application latency
+
Write-conflict activity
+
Transaction activity
+
Execution queues
+
CPU / I/O / Cache behavior
Looking at a single counter in isolation rarely identifies the root cause.
A Practical Troubleshooting Example
Suppose an application team reports increased MongoDB latency after a new release.
You observe that write-conflict activity has also increased.
The first reaction should not be:
“MongoDB locking has become a problem.”
Instead, investigate the workload.
You discover that the new application version updates a shared status document for every incoming request.
Previously:
Many clients
|
+–> Different documents
Now:
Many clients
|
+–> Same document
The application has created a hot document.
The increased write conflicts are now understandable.
The solution might be to distribute the workload, redesign the schema, or change the update pattern—not simply increase connection counts or change lock-related settings.
This is the value of understanding MVCC from a DBA perspective: database metrics become clues that can be connected back to application and schema behavior.
Key Takeaways
1. MVCC supports fine-grained concurrency.
WiredTiger’s MVCC, locking, and transaction mechanisms work together to provide appropriate data visibility and concurrent access.
2. Document-level concurrency control is not traditional document locking.
MongoDB combines storage-engine concurrency mechanisms with multi-granularity locks at higher resource levels.
3. Write conflicts are different from lock contention.
A WiredTiger write conflict should not automatically be interpreted as a lock wait or an application-level retry.
4. Hot documents can become bottlenecks.
The $inc operation is atomic, but concentrating a high write rate on the same document can create contention.
5. Long-running transactions require attention.
They do not automatically cause conflicts, but long-running transactions or snapshots can potentially increase history and cache pressure and extend overlap with concurrent operations.
6. Monitor trends, not isolated numbers.
Use current-operation information, transaction metrics, write-conflict counters, execution queues, and WiredTiger statistics together with application latency and workload behavior.
Conclusion
WiredTiger’s MVCC is an important part of how MongoDB handles concurrent workloads. For DBAs, the practical value lies in understanding how data visibility, document-level concurrency control, write conflicts, hot documents, and transaction duration affect production behavior.
When concurrency problems appear, the right question is not simply “What is locked?” Instead, ask:
“What operations are competing, what data are they accessing, and what changed in the workload?”
That perspective helps turn MongoDB concurrency metrics into useful signals for production troubleshooting.