Skip to content

Read and write concerns

A replica set keeps several copies of your data: one primary that takes all writes, and one or more secondaries that copy those writes over. This redundancy is what makes the durability and visibility knobs meaningful. When you write, you can decide how many of those copies must confirm the write before you consider it done. When you read, you can decide how committed and how fresh the data you get back must be. The two settings are the write concern and the read concern, and they let you slide between fast-but-weaker and slow-but-stronger on every operation.

A write concern has three parts. The w value says how many members must acknowledge the write: w: 1 means only the primary, while w: "majority" means a majority of the set has stored it — the level at which a write survives the loss of any single member. The j value, when true, requires the write to be flushed to the on-disk journal before it is acknowledged, so it survives a crash, not just a process restart. And wtimeout caps how long the driver waits for those acknowledgements before giving up with an error.

Here we insert a member and demand that a majority of the set confirms it, journalled, within five seconds:

db.members.insertOne(
{ name: "Grace", fines: 0 },
{ writeConcern: { w: "majority", j: true, wtimeout: 5000 } }
)

The acknowledgement comes back only once the majority has stored the write:

{ "acknowledged": true, "insertedId": "65f0b3d4e4b0a1c2e4b0a1e7" }

Read concern and read preference: how fresh, from where

Section titled “Read concern and read preference: how fresh, from where”

A read concern controls which version of the data a read may return. With local, you get whatever the member you queried has right now, even if that data could later be rolled back. With majority, you only see data that a majority of the set has stored, so what you read will not be undone. With linearizable, a read on the primary reflects every write that was acknowledged before it began — the strongest and slowest option. A separate setting, the read preference, chooses which member answers: primary always gives the freshest data, while secondary spreads read load across copies at the cost of possibly trailing slightly behind.

Here we read with a majority read concern from the primary, asking for data we know cannot be rolled back:

db.members
.find({ fines: 0 })
.readConcern("majority")
.readPref("primary")

Every step toward stronger guarantees costs latency. A w: 1 write returns the instant the primary has it; a w: "majority" write waits for the data to travel to and be stored by other members first. The flow below shows where that extra time goes:

flowchart TD
  C["Client sends a write"] --> P["Primary stores it"]
  P --> R1["Secondary one replicates"]
  P --> R2["Secondary two replicates"]
  R1 --> M{"Majority has stored it?"}
  R2 --> M
  P --> M
  M -->|"Yes"| ACK["Acknowledge to client — write is durable"]
With majority write concern the client waits until a majority of members has stored the write before it is acknowledged

In Compass: the connection settings dialog lets you set a default read preference for the whole session, so reads you run in the Documents tab can be routed to secondaries without changing each query.

  • w: "majority" is the sweet spot for durability that survives a failover; w: 1 is faster but a not-yet-replicated write can be lost if the primary fails right after acknowledging it.
  • wtimeout only bounds the wait. If it fires, the write may still have been applied on the primary — it just was not confirmed by enough members in time, so treat the timeout as uncertain, not as a clean failure.
  • Reading from a secondary with read preference secondary can return slightly stale data, because secondaries trail the primary. Pair it with a read concern that matches how fresh your application actually needs the data to be.
What does a write concern of w: "majority" guarantee?
What does the j option in a write concern require?
Which read concern only returns data a majority has stored?
What does read preference control?