Filter concepts by levelShowing all levels.

MongoDB · Section 26

Replica Set Architecture

Level
advanced
Read
30 min
Concepts
5

Majority as the single concept that unifies write concern, read concern, and elections; the distinction between voting and non-voting members and why MongoDB caps voting members at 7; how to reason through real failure scenarios — a primary crash versus a network partition, including why split-brain cannot happen under normal majority-based elections; how write concern and read preference behavior actually depends on the current topology's voting member count and placement; and the specialized member configurations — hidden, delayed, priority, and non-voting — that turn a plain secondary into a purpose-built role.

MongoDB overview

What is true here

  1. Majority = floor(voting members / 2) + 1, and this same number governs write concern, read concern, and elections — which guarantees any two majorities in the same set overlap.
  2. A member can hold a full data copy without voting rights — majority is computed against voting members only, and MongoDB caps voting members at 7.
  3. After any failure, only a group holding a majority of voting members can elect a primary and keep accepting writes — every other group is read-only, which is why split-brain cannot occur under normal elections.
  4. Write concern and read preference settings only mean something relative to the current topology — the same setting protects against different real-world failures depending on voter count and placement.
  5. hidden, delayed, priority, and non-voting are configuration dials on a normal secondary — combined, they build purpose-built roles like a recovery-window safety net.

What you will be able to do

  • Compute majority for a given voting member count
  • Explain the difference between a voting and a non-voting member, and why the 7-voter cap exists
  • Predict the outcome of a specific partition or failure scenario in a given topology
  • Reason about whether a write concern or read preference setting actually protects against a given real-world failure
  • Configure a hidden, delayed, non-voting member as a recovery safety net

Majority and membership

The threshold every durability guarantee in this topic shares, and the distinction between voting and non-voting members.

Majority, the unifying concept

standardadvanced

"Majority" means more than half of the replica set's voting members — a specific number computed from the set's configuration, not a vague idea of "most". It is the one number that write concern, elections, and majority read concern all key off, which is exactly why they interact safely with each other.

Think of it as

Every use of "majority" in MongoDB is asking the same underlying question: is this many voting members in agreement? A write concern of "majority" and an election both require that same threshold, which is precisely the structural reason a majority-acknowledged write can never be lost to a failover — the next primary is elected from a group that necessarily overlaps with any majority that already had the write.

text
majority = floor(votingMembers / 2) + 1

What we're doing: Show the overlap guarantee concretely in a 5-member set.

text
// 5 voting members, majority = 3
// A write concern "majority" write is confirmed by any 3 of the 5
// An election also requires 3 of the 5 to agree on a new primary
// -> any two groups of 3 out of 5 members MUST share at least one member
//    in common — so the new primary's group always includes at least one
//    member that already had the "majority" write
6
This overlap is guaranteed by simple counting — two groups of 3 drawn from only 5 total members cannot both be entirely disjoint.

Why this works: This overlap is not a coincidence or a probability — it is a guaranteed consequence of both operations requiring more than half of the same fixed set of voting members, which is exactly what makes "majority" the threshold every durability guarantee in this section is built on.

Remember: Majority = floor(votingMembers / 2) + 1, and the same threshold governs write concern, read concern, and elections — which is why any two majorities in the same set are guaranteed to overlap, and why that overlap is what protects a majority-committed write from being lost to a failover.

See also: voting members and elections · write concern acknowledgement and durability

Voting members and election implications

standardadvanced

Not every member of a replica set necessarily has a vote — a member can be configured with votes: 0, which excludes it from both voting in elections and ever becoming primary itself, while still holding a full copy of the data. The number of voting members is what "majority" is computed against.

Think of it as

Voting rights and holding a data copy are two separate properties of a member — most members have both, but a non-voting member (often used to keep the total voter count odd, or to add a read-only copy without changing election math) has only the second.

text
rs.add({ host: "m8:27017", votes: 0, priority: 0 })

What we're doing: Add an eighth member for extra read capacity without disturbing the existing 7-voter majority math.

javascript
// A set already has 7 voting members (the maximum). An 8th member is added
// purely for extra read capacity — it must be non-voting.
rs.add({ host: "reader-1:27017", votes: 0, priority: 0 })
3
votes: 0 keeps this new member out of the election and majority calculation entirely — it adds read capacity without changing what "majority" means for the other 7.

Why this works: Since MongoDB caps voting members at 7, any additional member beyond that has to be non-voting by necessity — this is also a deliberate design choice even below that cap, whenever more read/data copies are wanted without raising the majority threshold.

Remember: A member can hold a full data copy without being able to vote or become primary — the voting member count, not total member count, is what majority is computed against, and MongoDB caps voting members at 7.

See also: majority concepts · election and failover

Advertisement

Failure reasoning and specialized roles

Working through real failure scenarios, how concern settings depend on the actual topology, and the specialized member configurations available.

Failure scenarios: primary loss and partitions

coreadvanced

A single primary crash is the easy case — the remaining majority elects a new primary in seconds. A network partition is harder: it can split the set into two groups, and only the group holding a majority of voting members can elect a primary and keep accepting writes — the other side becomes read-only, unable to elect anyone.

Think of it as

Every failure scenario reduces to the same question: after this failure, does any remaining group still hold a majority of voting members? If yes, that group elects a primary and the set keeps working with reduced capacity. If no group does, the whole set loses its primary and cannot accept writes until enough members reconnect — this is the direct, deliberate consequence of majority-based elections, not a bug.

text
// After any failure: does any remaining group hold a majority of voting members? If yes, it elects. If no, the whole set has no primary.

What we're doing: Reason through a specific partition scenario in a 5-member set to predict the outcome.

text
// 5 voting members: A (primary), B, C, D, E — majority = 3
// A network partition isolates {A, B} from {C, D, E}

// {A, B}: 2 members, no majority -> A steps down, this side becomes read-only
// {C, D, E}: 3 members, has a majority -> elects a new primary from this side
// -> the application, if it can still reach {C, D, E}, keeps working;
//    if it can only reach {A, B}, it sees no primary and cannot write
4
Even though A was primary before the partition, being on the minority side (no majority) forces it to step down — it cannot safely keep accepting writes it cannot get acknowledged by a majority.
5
The side with 3 of 5 members has a majority and elects its own primary, allowing the set to keep functioning for any client that can reach that side.

Why this works: A would-be primary that can no longer reach a majority has to step down, because continuing to accept writes without majority acknowledgement would risk exactly the kind of un-recoverable divergence majority-based writes exist to prevent — the correct, safe behavior is unavailability on the minority side, not silent risk.

Deploying a majority of voting members across regions that a single network event can isolate together

Wrong

text
// 5-member set: 3 voting members in Region A, 2 in Region B — Region A alone already has a majority

Better

text
// Spread voting members so no single region's isolation leaves either side with a majority by coincidence, or so the majority region is the one you can actually tolerate depending on

What you see: A single region-level network event determines the outcome entirely — if Region A is isolated from Region B, Region A still has its majority and keeps working, but if Region A itself goes down, the whole set loses its primary even though Region B had 2 healthy members.

Why: Voting member placement directly determines which failure scenarios the set can tolerate — an unconsidered distribution can concentrate the majority in exactly the region most likely to fail as a unit (a single data center, a single cloud availability zone).

Partition with a majority side vs. no majority side

5 members split 3-2

  • +side with 3: has a majority, elects a primary
  • +side with 2: no majority, read-only, cannot elect
  • +the set keeps accepting writes, with reduced membership

3 members split 1-1-1 (triple partition)

  • no side has 2 of 3 — no majority anywhere
  • no primary can be elected on either side
  • the whole set is read-only until connectivity returns
  • 5 members split 3-2
    • side with 3: has a majority, elects a primary
    • side with 2: no majority, read-only, cannot elect
    • the set keeps accepting writes, with reduced membership
  • 3 members split 1-1-1 (triple partition)
    • no side has 2 of 3 — no majority anywhere
    • no primary can be elected on either side
    • the whole set is read-only until connectivity returns

Remember: After any failure, ask: does any remaining group hold a majority of voting members? That group elects and keeps working; every other group (including "no group at all") has no primary and is read-only until connectivity or membership is restored.

See also: majority concepts · election and failover

How concern settings interact with topology

standardadvanced

Write concern "majority" and read preference are not abstract settings — their real behavior depends on how many voting members exist and where they are placed. The same w: "majority" write concern needs 2 acknowledgements in a 3-member set but 4 in a 7-member set, and a read preference targeting the "nearest" member behaves completely differently in a single-region set versus a globally distributed one.

Think of it as

Treat write concern and read preference as settings that only make sense in the context of an actual topology — the number and placement of voting members, and where the application connects from. The same setting can be perfectly safe in one topology and create an availability trap in another.

text
// Re-derive: what does "majority" require, and where do "nearest"/"secondaryPreferred" reads actually land, for THIS topology specifically?

What we're doing: Show the same write concern behaving differently in two topologies with different voting member counts.

text
// Topology A: 3 voting members, all in one data center
// w: "majority" needs 2 of 3 — tolerates 1 member failing, but not a
// whole-data-center outage, since all 3 are in the same place

// Topology B: 5 voting members across 3 regions (2, 2, 1)
// w: "majority" needs 3 of 5 — tolerates a whole region's 2 members going
// down and still has a majority among the remaining 3
3
Topology A's single-data-center placement means the majority requirement protects against individual server loss, but not the specific failure mode (the whole data center) that matters most in practice.
8
Topology B's spread across three regions means the same "majority" concept now tolerates a whole-region loss, because no single region holds enough voting members to prevent the remaining ones from reaching a majority.

Why this works: w: "majority" is a relationship to the current topology, not a fixed guarantee — the same setting name protects against very different real-world failures depending on how many voting members exist and, critically, where they physically sit.

Remember: Write concern and read preference only mean something in the context of an actual topology — re-derive what "majority" requires and where reads actually land whenever voting member count or placement changes, not just once at initial setup.

See also: majority concepts · failure scenarios · read preference modes

Hidden, delayed, priority, and non-voting members

standardadvanced

Beyond plain secondaries, a replica set member can be configured for a specific job: hidden (invisible to application read routing, used for dedicated backup/reporting), delayed (intentionally behind by a fixed window, a safety net against accidental data loss), priority-adjusted (more or less likely to be elected primary), or non-voting (holds data, no say in elections).

Think of it as

Each of these is a dial on a normal secondary, not a separate kind of server — a member can combine several: hidden and delayed together is a common "undo button" configuration, invisible to the application and running a fixed distance behind in case something needs to be recovered from before it happened.

text
{ hidden: true, secondaryDelaySecs: <n>, priority: <n>, votes: 0 | 1 }

What we're doing: Configure a delayed member as a recovery safety net against an accidental mass delete.

javascript
// A member deliberately kept 1 hour behind, hidden from reads, and unable
// to vote or become primary — purely a recovery safety net
const cfg = rs.conf()
cfg.members[3].hidden = true
cfg.members[3].secondaryDelaySecs = 3600
cfg.members[3].priority = 0
cfg.members[3].votes = 0
rs.reconfig(cfg)

// If a bad deploy runs deleteMany({}) by mistake, this member still has the
// pre-deletion data for up to an hour — enough time to intervene
4
secondaryDelaySecs: 3600 is what actually creates the recovery window — this member will not have replicated a mistake made less than an hour ago.
5
priority: 0 and votes: 0 keep this member out of both the election and any normal read routing, since it exists purely as a delayed copy, not a production-serving one.

Why this works: A delayed member is a deliberate trade of storage and one extra server for a real, low-tech safety net against the specific class of incident — an accidental mass write or delete — that a normal backup taken once a day might not catch in time.

Specialized member configurations

Specialized member configurations
ConfigEffectTypical use
hidden: trueinvisible to read routingdedicated backup/reporting member
secondaryDelaySecs: Nlags N seconds behind primaryrecovery window for accidental writes
priority: 0can never become primarya member in a less-preferred location
priority: >1more likely to be electedpreferring a specific, well-provisioned member
votes: 0excluded from elections/majorityextra read/data copy without changing election math

Together

javascript
cfg.members[3].hidden = true
cfg.members[3].secondaryDelaySecs = 3600  // 1 hour behind
cfg.members[3].priority = 0
cfg.members[3].votes = 0
rs.reconfig(cfg)

Remember: hidden, delayed, priority, and non-voting are dials on a normal secondary, not separate server types — combined (hidden + delayed + non-voting), they make a low-tech but effective recovery safety net against accidental data loss.

See also: voting members and elections · primary and secondary members

Advertisement