skip to content

Why does a MongoDB replica set with four voting members tolerate no more failures than one with three?

level: middleimportance: must knowfreq 68%

answer

  1. Count the votes, then halve it
  2. Strict majority, not half
  3. Compare three members against four
  4. Denominator is configured, not reachable
  5. Four splits two-two with no winner

basics

~20 s

Electing a primary needs a strict majority of the configured voting members. Three members need two votes, four need three, so both survive exactly one loss. The fourth vote adds cost and tie risk without adding fault tolerance.

solid answer

~50 s

A MongoDB replica set elects a primary only when a candidate collects votes from a strict majority of the **configured** voting members, and the count is over configured members, not reachable ones. With three voting members the majority is two, so one member may be down. With four, the majority is three — still only one member may be down. Going from three to four buys nothing and costs something: you now have a partition shape (2 versus 2) where neither side holds a majority, so the whole set goes read-only even though every node is healthy. The first count that actually improves tolerance is five, whose majority of three survives two losses. If you want a fourth copy of the data for reads or backups without disturbing the arithmetic, add it with `votes: 0` and `priority: 0`.

code

javascript · 5 lines
javascript
// Add a fourth copy without adding a fourth vote
cfg = rs.conf();
cfg.members[3].votes = 0;
cfg.members[3].priority = 0; // required when votes is 0
rs.reconfig(cfg);

go deeper

for a junior

Recall the rule itself: a new primary needs votes from more than half the voting members, and replica sets are deployed with an odd number of voters for that reason.

for a middle

Be ready to derive the fault-tolerance table on the spot and explain that the denominator is the configured voting membership, so a downed node does not lower the bar for a quorum.

for a senior

Show the operational consequence: name the two-versus-two partition where a healthy four-voter set goes read-only, and know that votes: 0 plus priority: 0 is how you add copies without touching the arithmetic.

for a principal

Own the placement argument — how many voters, in how many failure domains, and what tolerance you are actually buying versus the coordination and latency cost of each additional voter.

## What an election actually requires A MongoDB replica set has one primary that accepts writes and a number of secondaries that replicate from it. When the primary becomes unreachable, the remaining members hold an election to choose a new one. The rule that governs the outcome is simple and is the whole content of this question: **a candidate becomes primary only if it receives votes from a strict majority of the voting members listed in the replica set configuration.** Two words in that sentence do most of the work. - **Strict majority** means more than half — not half, not "the most votes". For `n` voting members the threshold is `floor(n/2) + 1`. - **Configured**, not reachable. The denominator is the number of members with `votes: 1` in `rs.conf()`. Taking a machine offline does not shrink the denominator; only an `rs.reconfig()` that removes the member or sets its `votes` to 0 does. ## The arithmetic, member by member | Voting members | Majority needed | Failures tolerated | |---|---|---| | 3 | 2 | 1 | | 4 | 3 | 1 | | 5 | 3 | 2 | | 6 | 4 | 2 | | 7 | 4 | 3 | Every even count sits on the same tolerance as the odd count below it. Four tolerates what three tolerates; six tolerates what five tolerates. Adding the even-numbered vote raises the bar for a quorum by one at exactly the same time it adds one more thing that can fail, so the two effects cancel. ## Why the even count is worse than merely useless The wasted vote is the mild part. The real cost is the shape of the failure you have just made possible: a clean split down the middle. With four voting members separated into two groups of two — by a network partition, a rack switch, a site link — neither group holds three votes. Neither can elect a primary. The set has no writable node while every single process is alive and healthy. With three voting members no such symmetric split exists; one side always has two of three and stays writable. That is also why MongoDB caps voting members at seven and recommends an odd number: the odd counts are the only ones where every partition has a majority side. ## Voting members are not the same as data-bearing members A replica set may contain up to 50 members but at most 7 of them may vote. This split is the escape hatch when you want more copies than the voting arithmetic likes. A member configured with `votes: 0` replicates data, can serve reads, and can be used for backups or analytics — it just takes no part in elections. MongoDB requires such a member to also have `priority: 0`, since a member that cannot vote must not be able to trigger or win an election either. So the correct response to "we want a fourth copy in another rack" is not "add a fourth voter"; it is "add a fourth member with `votes: 0, priority: 0`", or go all the way to five voters if you genuinely want to survive two simultaneous losses. ## The arbiter temptation The mirror-image mistake is reaching for an arbiter to fix an even count. An arbiter is a member that votes but stores no data, so it does turn a two-member set into a three-vote set that can elect. But it contributes no replica of your data, cannot acknowledge a `w: "majority"` write, and leaves you one data-bearing failure away from having a single copy. Using an arbiter to reach an odd number is defensible in a resource-constrained deployment; using one where a real data-bearing member would fit is not, and modern MongoDB guidance is to prefer three data-bearing members over primary-secondary-arbiter. ## Consequences when the majority is lost If no candidate can reach a majority, the set has no primary. Writes fail — drivers cannot select a writable server — while secondaries continue to serve reads for clients that asked for a non-primary read preference. This is deliberate: refusing writes is how MongoDB avoids two primaries accepting divergent writes at once. The cluster does not "pick the bigger half" or "pick the freshest node"; without a majority it simply stays read-only until enough members come back or an operator reconfigures the set. ## What interviewers are testing This question separates people who memorised "use an odd number of members" from people who can derive it. The derivation is one line of arithmetic plus the observation that the denominator is the configured membership. If you can also name `votes: 0` as the way to add copies without adding voters, you have answered the follow-up before it is asked.

  • You want a fourth copy of the data in another rack. How do you add it without changing the election arithmetic?
    Add it as a non-voting member: `votes: 0` together with `priority: 0` (MongoDB requires the priority to be zero when votes are zero). It performs initial sync, tails the oplog and can serve reads or feed backups, but it is not counted in the majority and cannot be elected. The set still needs two of its three voters to elect a primary.
  • A five-member set loses two members permanently to a dead data centre. The remaining three elect fine. What should you do next, and why?
    Reconfigure the set to drop the dead members with `rs.reconfig()`. Until you do, the majority is still calculated over five configured voters, so the surviving three are one failure away from being read-only. After the reconfig the denominator is three, the majority is two, and the set can again lose one member and stay writable.
  • Does adding an arbiter to a four-member set fix the problem?
    It fixes the arithmetic but not the design. Five voters give a majority of three and survive two losses. However the arbiter holds no data, cannot acknowledge a `w: "majority"` write, and does not raise the number of copies of your data. Prefer a fifth data-bearing member; use an arbiter only when a real member genuinely cannot be provisioned.

saying these in an interview costs you the question

  • Says four voters tolerate two failures
  • Counts majority over reachable members, not configured ones
  • Thinks the largest surviving group always wins
  • Assumes an arbiter adds data redundancy
  • Believes MongoDB breaks a tie by oplog freshness

context