Causal Consistency
Parent: MongoDB Replication · researched 2026-05-29T14:39:34.623Z· 2 sources · 8 concepts · skill mongodb-replication
MongoDB replication provides redundancy and high availability through replica sets -- groups of mongod processes that maintain the same data set. A replica set contains one primary member that receive
Overview
- MongoDB replication provides redundancy and high availability through replica sets -- groups of mongod processes that maintain the same data set. A replica set contains one primary member that receives all writes and one or more secondary members that replicate the primary's data asynchronously via the oplog (operations log). Replica sets are the foundation of MongoDB's data durability, fault tolerance, and read scaling strategy. [source]
- Key guarantees of a properly configured replica set: [source]
- Automatic failover: if the primary becomes unavailable, an election promotes a secondary to primary within ~12 seconds (median, with default settings). [source]
- Data redundancy: every data-bearing member holds a complete copy of the data set. [source]
- Read scaling: applications can distribute reads across secondaries using read preferences. [source]
- Tunable consistency: write concern and read concern let applications choose their durability and consistency guarantees per operation. [source]
1.1 Member Types
- Primary: The only member that accepts write operations. Records all writes to its oplog. At most one primary per replica set at any time. [source]
- Secondary: Maintains an identical copy of the primary's data set by asynchronously applying operations from the primary's oplog. Can serve read operations when read preference allows it. Can be elected primary during failover. [source]
- Arbiter: Participates in elections but holds no data. Provides a tiebreaking vote in even-member-count topologies. Must not run on the same system as primary or secondary members. Has exactly 1 election vote and a default priority of 0. [source]
- Hidden Members: Must have priority: 0, so they cannot become primary. Excluded from default client read routing. Use for dedicated tasks: reporting queries, backups, analytics workloads. Only reachable by direct connection. [source]
- Delayed Members: Maintain a time-delayed copy of the data (configured via secondaryDelaySecs). Must be hidden and should be non-voting. Serve as a defense against accidental data destruction -- the delayed copy preserves the state from N seconds ago. [source]
1.3 Recommended Topologies
- Three-member replica set (P-S-S): One primary, two secondaries. Minimum recommended production topology. Tolerates one member failure while maintaining majority for elections and w: "majority" writes. [source]
- Primary-Secondary-Arbiter (P-S-A): Costs less but carries availability risk. If the sole data-bearing secondary goes down, w: "majority" writes fail. Avoid in sharded clusters. [source]
- Geographically distributed: Place members across data centers. Ensure majority of voting members resides in the primary data center. [source]
2.1 Election Triggers
- Elections occur when: a new node is added; the set is initiated with rs.initiate(); maintenance commands run (rs.stepDown(), rs.reconfig()); secondaries lose connectivity to primary for longer than electionTimeoutMillis (default 10s); or the primary detects it can see only a minority of voting members. [source]
2.2 Election Protocol (pv1)
- MongoDB uses Raft-based consensus (pv1): heartbeats every 2 seconds; if no heartbeat within 10s member is marked inaccessible; candidate runs dry election first; first member to receive majority of votes becomes primary. [source]
2.3 Priority and Votes
3.1 What Is the Oplog
- The oplog (local.oplog.rs) is a capped collection recording all write operations in idempotent format. Every member maintains its own oplog. Secondaries copy and apply entries from the primary's oplog. [source]
3.3 Oplog Window
- The oplog window is the time between the newest and oldest oplog entry. A secondary that falls behind more than the oplog window must perform a full initial sync. [source]
4. Write Concern
- Write concern controls durability before the server acknowledges a write. [source]
4.3 `j` (Journal) Option
4.4 `wtimeout`
- Time limit (ms) for propagation. Does not undo applied writes on timeout. 0 = wait indefinitely. [source]
4.5 Default Write Concern
- MongoDB 5.0+: { w: "majority" } for most deployments. Exception: P-S-A topologies default to { w: 1 }. [source]
4.7 Write Concern and Transactions
- Set at transaction level, not per-operation: [source]
5. Read Preference
- maxStalenessSeconds (min 90s) excludes secondaries lagging beyond threshold. [source]
6.4 Causal Consistency (summary)
- Use rc: "majority" + wc: "majority" for causal consistency. MongoDB sets afterClusterTime automatically in causally consistent sessions. See §17 for full coverage. [source]
7.1 When Rollbacks Occur
- A rollback reverts writes on a former primary when it rejoins after failover, when those writes had not replicated to a majority before the primary stepped down. [source]
7.2 Rollback Algorithms
7.4 Preventing Rollbacks
- Use { w: "majority" }. Enable journaling. Monitor replication lag. Avoid P-S-A topologies. [source]
8. Replication Lag Diagnosis
9. Initial Sync
10. Change Streams Over Replica Sets
- Every change event has a resume token (_id). Use resumeAfter to resume from a token; startAfter to resume even after invalidate events. Tokens expire when oplog entry is truncated. [source]
- MongoDB 6.0+: fullDocumentBeforeChange and fullDocument: 'updateLookup' for pre/post images (requires changeStreamPreAndPostImages on collection). [source]
11. Replica Set Maintenance
- Rolling maintenance: maintain secondaries first, then rs.stepDown() and maintain former primary. [source]
13. Troubleshooting Checklist
- Election not completing: verify majority reachable (rs.status()), check electionTimeoutMillis, check for network partition. [source]
- Replication lag: rs.printSecondaryReplicationInfo(), check disk I/O, index builds (db.currentOp()), flow control (serverStatus.flowControl). [source]
- Rollback occurred: inspect <dbpath>/rollback/, check write concern used, bsondump rolled-back BSON. [source]
- Initial sync failing: verify oplog window size, disk space, sync source state, network connectivity. [source]
15. Cross-References
- mongodb-expert: General MongoDB architecture and operations. [source]
- mongodb-atlas-expert: Atlas-managed replica sets and Atlas-specific settings. [source]
- mongodb-data-lifecycle: Change streams deep coverage, CDC architectures, pre/post images. [source]
- mongodb-sharding: Sharded cluster replication, config server replica sets, chunk migration. [source]
- mongodb-performance-troubleshooting: Replication lag analysis, slow oplog application. [source]
- mongosync: Inter-cluster replication - Atlas Live Migration, C2C Sync, active-passive DR. [source]
16.1 Read Concern Levels Comparison
- "local": Returns the most recent data on the targeted node with no majority confirmation. On a secondary, data may not yet be replicated to a majority of members and could be rolled back if the current primary fails before replication completes. This is the default for find, aggregate, and getMore operations. [source]
- "available": Identical to "local" on replica set members. On sharded clusters it diverges: reads are served directly from the shard that owns the chunk without consulting config servers for up-to-date routing metadata. During chunk migrations this can return orphaned documents. Avoid on sharded collections for any consistency-sensitive reads. [source]
- "majority": Returns only data acknowledged by a majority of data-bearing voting members and written to the majority-committed oplog point. Guaranteed durable; will never be rolled back. Requires WiredTiger (only storage engine since MongoDB 5.0). [source]
- "linearizable": Strongest single-document consistency guarantee. Reads block until the server confirms no write started before the read is still in-flight at a majority. Always targets the primary. Must be combined with maxTimeMS. Cannot be used with $out, $merge, or multi-document transactions. [source]
- "snapshot": Returns data from a consistent snapshot of majority-committed data at a single point in time. Primarily used in multi-document transactions. When a transaction commits with w: "majority", the snapshot guarantee is preserved end-to-end. [source]
16.2 Majority Read Concern Mechanics
- MongoDB maintains an internal majority-committed optime - the oplog timestamp up to which a majority of data-bearing voting members have confirmed replication. The primary advances this by computing the highest optime for which floor(votingMembers/2)+1 members have reported an optime >= that value, every heartbeat cycle (~2s). [source]
- WiredTiger maintains an in-memory read snapshot pegged to the majority-committed optime. "majority" reads access this snapshot directly - they do not block writes and add negligible latency in steady state. [source]
- The interaction with w: "majority" write concern is tight: a write acknowledged at w: "majority" has by definition advanced the majority-commit point to at least its optime. A subsequent read with read concern "majority" (rc: "majority") on any node will therefore see that write - this is the foundation of the causal consistency guarantee. (rc: is used as shorthand for "read concern level" throughout §16–17.) [source]
16.3 Linearizable vs Snapshot — When to Choose Each
- Choose "linearizable" when: [source]
- You need the absolute freshest majority-committed data for a single document. [source]
- You are building a compare-and-swap or test-and-set operation. [source]
- Always pair with maxTimeMS to bound the blocking window. [source]
- Choose "snapshot" when: [source]
- You need a consistent view across multiple documents or collections within a transaction. [source]
- You want point-in-time consistency without the primary-only restriction of "linearizable". [source]
- Key difference: "linearizable" waits for in-flight writes before responding (most current possible). "snapshot" reads from a fixed point in time and does not wait. [source]
16.4 Read Concern in Sharding — `"available"` vs `"local"` Divergence
- For sharded clusters, default to "local" or "majority". "available" exists primarily as a performance optimization for non-sharded workloads. [source]
16.6 Code Examples — Setting Read Concern
17.1 What Causal Consistency Means
- Causal consistency guarantees that operations within a session (or across sessions sharing causal tokens) observe a logically consistent sequence of writes: [source]
- MongoDB implements causal consistency through two logical clocks in every server response: [source]
- $clusterTime: A hybrid logical clock (HLC) providing total ordering across the replica set. Every server response includes the current $clusterTime. [source]
- operationTime: The optime of the most recent operation in the session. Clients send it as afterClusterTime on the next read. [source]
- When a read is issued with afterClusterTime: T, the server waits until its majority-committed optime >= T before executing, ensuring the read sees all writes up to time T. [source]
17.2 Session Setup and Lifecycle
- Node.js driver session API: [source]
- Key session methods: [source]
- session.advanceClusterTime(clusterTime) - advance session cluster time (for cross-service token passing). [source]
- session.advanceOperationTime(operationTime) - advance operation time (same purpose). [source]
- session.endSession() - always call in a finally block. [source]
17.3 Why Read Concern `"majority"` Is Required for Causal Consistency
- With "local" read concern, afterClusterTime still runs but data returned may include not-yet-majority-committed writes that could be rolled back, breaking the causal chain. [source]
- With "majority", data is from the permanent majority-committed snapshot. The causal chain holds because both write (w: "majority") and read (rc: "majority") anchor to the same majority-commit point. [source]
- "linearizable" also satisfies causal consistency but adds primary-only and in-flight-write-wait constraints - overkill for most causal use cases. [source]
17.4 Causal Consistency Across Multiple Clients
- When this pattern is essential: writing via one API service then reading via another; sequential user actions where step 2 must see step 1; reading your own writes from a secondary. [source]
17.6 Implicit vs Explicit Sessions
- Every MongoDB operation uses a session, even if you do not create one explicitly. [source]
- Key implications: [source]
- Implicit sessions provide no causal ordering guarantees between operations. [source]
- Explicit sessions maintain clusterTime and operationTime across all operations. [source]
- Multi-document transactions always require an explicit session. [source]
- Explicit sessions are lightweight - negligible cost for the duration of a request-response cycle. Exception: sessions with an active transaction hold a WiredTiger snapshot and should be kept short to avoid cache pressure (see §17.7). Always call endSession(). [source]
- Implicit sessions are fine for fire-and-forget writes where read-your-writes is not required. [source]
17.7 Common Pitfalls
- (rc: = read concern level shorthand used below.) [source]
Children
- client sessions (frontier)
- afterClusterTime (frontier)
- operationTime (frontier)
- clusterTime (frontier)
- read your own writes (frontier)
- monotonic reads (frontier)
- implicit vs explicit sessions (frontier)
- cross-service causal tokens (frontier)
Frontier under this node: afterClusterTime, client sessions, clusterTime, cross-service causal tokens, implicit vs explicit sessions, monotonic reads, operationTime, read your own writes