MongoDB's formal verification of its distributed transaction protocol reveals that correctness isn't binary—protocols implementing the same isolation level can vary significantly in permissiveness, directly impacting performance and concurrency.
Distributed transactions have become increasingly critical as applications scale across multiple data centers and geographic regions. MongoDB's implementation of multi-document, cross-shard transactions since 2019 provides ACID guarantees at snapshot isolation, but ensuring both correctness and performance at scale requires sophisticated verification approaches. Recent work by MongoDB engineers demonstrates how formal methods can move beyond simple correctness checking to provide quantitative insights into protocol performance characteristics.
The Challenge of Distributed Transaction Verification
The complexity of distributed systems makes traditional testing approaches insufficient for guaranteeing correctness. MongoDB's distributed transaction protocol operates across multiple layers: the high-level distributed protocol coordinates across shards, while the underlying WiredTiger storage engine handles local key-value operations. This layered architecture creates numerous interaction points where subtle bugs can emerge.
To address this challenge, MongoDB developed compositional TLA+ specifications that model the transaction protocol at an abstract level while formalizing the interface boundary with WiredTiger. This compositional approach allows verification of high-level isolation guarantees without getting lost in implementation details. The specifications enable checking whether committed transaction histories satisfy snapshot isolation, read committed isolation, and other consistency properties.
Using the TLC model checker, these specifications can verify isolation guarantees for small instances of the problem—typically two transactions and two keys—in around 10 minutes using 12 cores. While the state space grows quickly, bugs tend to manifest even in these small instances, making this approach practical for finding critical issues early in development.
The Two-Phase Commit Protocol in Practice
MongoDB's distributed transactions use a variant of two-phase commit (2PC) to ensure atomicity across shards. When a client begins a transaction, the associated mongos router assigns a global read timestamp and routes operations to appropriate shards. Upon successful execution, the router initiates 2PC by handing off to a coordinator shard, which sends prepareTransaction messages to all participants.
During the prepare phase, each shard selects a prepare timestamp and persists a prepare log entry in its replica set. This ensures durability of the prepare state. The coordinator then computes a commit timestamp greater than or equal to all received prepare timestamps and sends commitTransaction commands to all shards. Each shard commits locally, making the transaction's writes visible at the commit timestamp.
A critical aspect of this design is the timestamp blocking behavior. When a shard enters the prepare phase, it marks keys as prepared at the storage engine layer. Any read at a timestamp greater than or equal to this prepared timestamp must block, since the commit timestamp isn't yet known. This blocking ensures consistency but can impact performance if not carefully managed.
Introducing Permissiveness: A New Performance Metric
The most innovative aspect of MongoDB's formal verification work is the introduction of permissiveness as a quantitative metric for comparing transaction protocols. While traditional verification focuses on whether a protocol correctly implements an isolation level, permissiveness measures how restrictive the protocol is in practice.
For any transaction protocol implementing a given isolation level, permissiveness captures the ratio between the number of transaction schedules the protocol actually allows versus the number theoretically permitted by the isolation definition. This metric reveals that correct protocols implementing the same isolation level can vary significantly in their concurrency characteristics.
Computing permissiveness involves projecting the full reachable state graph onto its transaction history variable—the record of all committed transactions and their operation histories. The cardinality of this projected set, divided by the set of all transaction schedules allowed by the isolation definition, yields the permissiveness ratio. Higher ratios indicate more concurrent execution opportunities and potentially better performance.
Practical Implications for Protocol Design
This quantitative approach to protocol analysis provides concrete guidance for optimization. By measuring permissiveness under different conditions—such as varying conflict detection strategies or isolation levels—engineers can identify bottlenecks and opportunities for improvement. For example, MongoDB's readConcern: "local" isolation level can be compared against general read-committed definitions to understand the trade-offs between weaker isolation and increased concurrency.
The permissiveness metric also enables systematic exploration of design alternatives. Engineers can analyze how different conflict handling strategies impact concurrency, helping to find the sweet spot between correctness guarantees and performance requirements. This moves protocol design from an art based on intuition to an engineering discipline grounded in quantitative analysis.
Benefits for Application Developers
For developers building applications on MongoDB, this formal verification approach provides several concrete benefits. First, it offers stronger confidence that distributed transactions behave correctly across all layers, reducing the risk of subtle bugs that might only manifest under specific load patterns or failure scenarios. Second, by quantifying permissiveness, developers can trust that their applications make efficient use of system capacity, with fewer unnecessary aborts and retries.
The compositional specification approach also enables automatic model-based testing of the underlying WiredTiger storage engine. By formalizing the storage interface contract, engineers can verify that the implementation matches the abstract specification, catching discrepancies that might otherwise go unnoticed until production.
Looking Forward: The Future of Protocol Verification
MongoDB's work demonstrates that formal methods can provide value beyond binary correctness outcomes. By introducing quantitative metrics like permissiveness, verification becomes a tool for performance optimization rather than just bug detection. This approach is particularly valuable for distributed systems where the interaction between correctness and performance is complex and non-obvious.
The success of this approach suggests broader applications across the distributed systems landscape. As systems grow more complex and failure modes become more subtle, quantitative verification metrics could become standard practice for protocol design and optimization. The ability to measure not just whether a protocol is correct, but how efficiently it implements its guarantees, represents a significant advance in distributed systems engineering.
For the MongoDB community, this work provides both theoretical foundations and practical tools for understanding and improving distributed transaction performance. The specifications and analysis code are available in the associated repository, enabling other researchers and engineers to build upon this work and apply similar techniques to their own systems.
As distributed systems continue to evolve, the combination of formal verification for correctness and quantitative metrics for performance will likely become essential tools in the systems engineer's toolkit. MongoDB's approach shows how these techniques can be applied in practice to build systems that are not only correct but also efficient and scalable.

Comments
Please log in or register to join the discussion