Filter concepts by levelShowing all levels.

MongoDB · Replication

Replication

How replica sets stay in sync, survive failure, and what reading from a secondary actually costs

  • One primary, many secondariesall writes go to the primary; secondaries replicate it
  • The oplog is the mechanismsecondaries tail and replay it, not copy raw files
  • Elections are automatica majority vote picks a new primary in seconds
  • Lag = stalenessa secondary read can miss a write still in flight to it

1.Replica sets

A replica set is a group of MongoDB servers holding the same data, so the loss of any one of them does not mean data loss or downtime. One member is the primary and accepts writes; the others are secondaries that continuously copy the primary's changes.

Key features

  • A production replica set typically has an odd number of voting members (3, 5, 7) — odd counts avoid ties in an election
  • Exactly one member is primary at a time; all writes go to it
  • Secondaries continuously replicate the primary's oplog and apply the same changes
  • If the primary becomes unreachable, the remaining members elect a new primary automatically, without operator intervention
  • This is MongoDB's baseline high-availability building block — running production MongoDB as a lone standalone server is specifically what a replica set exists to avoid
A three-member replica set
writesoplogoplog

Application

sends writes

Primary

accepts all writes

Secondary

replicates from primary

Secondary

replicates from primary

  • Application — sends writes
    • leads to Primary (writes)
  • Primary — accepts all writes
    • leads to Secondary (oplog)
    • leads to Secondary (oplog)
  • Secondary — replicates from primary
  • Secondary — replicates from primary

Command

text
rs.initiate({ _id: "rs0", members: [{ _id: 0, host: "m1" }, { _id: 1, host: "m2" }, { _id: 2, host: "m3" }] })

A replica set is several servers holding the same data, one primary accepting writes at a time, with automatic election of a new primary if the current one becomes unreachable — this is MongoDB's baseline answer to "what happens when one server dies".

2.Primary and secondary members

The primary is the one member accepting writes at any moment; secondaries continuously apply the same changes the primary made, and can optionally serve reads. Which member is primary can change over time — it is a role, not a fixed identity of one particular server.

Key features

  • Exactly one member holds the primary role at any given moment — the replica set enforces this
  • All writes go to the primary; a write sent to a secondary is rejected
  • Secondaries replicate the primary's oplog and apply the same operations in the same order
  • Reads can be served from secondaries if the application's read preference allows it — by default, reads also go to the primary
  • A member's role can change over the set's lifetime — an election can promote a secondary to primary, and a recovered former-primary rejoins as a secondary

Command

text
db.hello() (or rs.status()) — reports which member currently holds the primary role

Primary and secondary are roles, not permanent identities — exactly one member is primary at a time, all writes go there, and which member holds that role can change across an election.

3.Replication via the oplog

The oplog is a special capped collection on the primary recording every write in order. Secondaries continuously read the primary's oplog and apply the same operations themselves — that is the actual mechanism behind "secondaries stay in sync".

Key features

  • The oplog lives in a capped collection (local.oplog.rs), fixed in size — older entries are overwritten as new ones are written
  • Each oplog entry is idempotent — applying it more than once has the same effect as applying it once, which is what makes replication safe to resume after an interruption
  • The oplog size determines the "replication window" — how much time a secondary can be disconnected before it falls too far behind to catch up incrementally
  • A secondary that falls further behind than the oplog's retained history needs a full resync, not just catching up
  • The oplog is also what change streams are built on — both features read the same underlying stream of operations

Command

text
// local.oplog.rs — a capped collection on the primary; secondaries tail it continuously

Secondaries replicate by tailing the primary's oplog — a capped, idempotent record of every write — and replaying it, not by copying raw data files. The oplog's fixed size sets the replication window for how long a disconnect can last before a full resync is needed.

4.Elections and failover

When the primary becomes unreachable — a crash, a network partition, a planned step-down — the remaining voting members hold an election and pick a new primary automatically, typically within a few seconds. The application does not need to intervene, though it does experience a brief window where writes fail.

Key features

  • Triggered by: primary unreachable (crash, network partition), or a deliberate step-down (rs.stepDown(), maintenance)
  • A new primary requires votes from a majority of the set's voting members — this is why odd member counts avoid ties
  • Among eligible candidates, the one with the most up-to-date replicated data is preferred
  • A typical election completes in a few seconds, during which the replica set has no primary and cannot accept writes
  • Application drivers detect the new primary automatically and resume routing writes to it — no manual reconfiguration needed
A member's role across a failover
primary becomesunreachablewins majorityvotesteps down / losescontact with majority

Secondary

Candidate (during election)

Primary

  • Secondary
    • → Candidate (during election) when primary becomes unreachable
  • Candidate (during election)
    • → Primary when wins majority vote
  • Primary
    • → Secondary when steps down / loses contact with majority

Command

text
rs.stepDown(<secs>) — deliberately trigger an election, e.g. before planned maintenance on the current primary

An election picks a new primary by majority vote among reachable members, preferring the one with the most up-to-date data — a few-second write-unavailability window during this process is expected behavior, not a failure.

5.What read preference controls

Read preference decides which member(s) of a replica set a read is allowed to go to — the primary only, secondaries, or a mix — independent of write concern, which is a completely separate setting about writes.

Key features

  • Read preference is set on the connection, a specific query, or a session — it does not affect where writes go, only reads
  • The default is primary — all reads go to the same place all writes do, guaranteeing the most up-to-date data
  • Reading from a secondary trades some data recency for spreading read load across more members, or reading from a geographically closer one
  • Read preference and read concern are independent settings answering different questions: "which member" versus "how safe is the data returned"
  • A read preference that allows secondaries does not guarantee a secondary is actually used — it is eligible to be, depending on availability and the specific mode

Command

text
db.collection.find({...}).readPref("secondaryPreferred")

Read preference decides which member a read is allowed to reach — primary for guaranteed-latest data, secondaries to spread load or reduce latency at the cost of some recency. It is independent of write concern and read concern.

6.The five read preference modes

Five named modes cover every point on the primary-vs-secondary, guaranteed-vs-best-effort spectrum: primary (only), primaryPreferred (primary if reachable, else secondary), secondary (only), secondaryPreferred (secondary if reachable, else primary), and nearest (whichever member has the lowest network latency, primary or secondary).

Key features

  • primary: only the primary — fails if no primary is currently available (e.g. mid-election)
  • primaryPreferred: primary if reachable, otherwise falls back to a secondary
  • secondary: only a secondary — fails if none is available, even if the primary is healthy
  • secondaryPreferred: a secondary if one is reachable, otherwise falls back to the primary
  • nearest: whichever member (primary or secondary) has the lowest measured network latency to the client

The five modes

The five modes
ModePrefersFalls back toTypical use
primaryprimary onlyfails (no fallback)anything needing guaranteed-latest data
primaryPreferredprimarysecondarymostly-latest reads that can tolerate brief fallback
secondarysecondary onlyfails (no fallback)reads that must never touch the primary
secondaryPreferredsecondaryprimaryread-heavy workloads that can tolerate some staleness
nearestlowest-latency member—latency-sensitive reads, geographically distributed clients

Command

text
.readPref("primary" | "primaryPreferred" | "secondary" | "secondaryPreferred" | "nearest")

primary/secondary have no fallback and fail if their target is unreachable; primaryPreferred/secondaryPreferred fall back to the other; nearest picks by latency regardless of role — match the mode to what the read can actually tolerate.

7.Replica lag

Replica lag is how far behind a secondary is in applying the primary's oplog — measured in time, not operation count. Under normal conditions it is milliseconds; under load, network issues, or a slow secondary, it can grow to seconds or more, and that gap is exactly how stale a read from that secondary can be.

Key features

  • Measured as the difference between the primary's latest oplog timestamp and a secondary's latest applied oplog timestamp
  • Normally milliseconds on a healthy, adequately-provisioned set — it grows under write load spikes, network issues, or an underpowered secondary
  • rs.printSecondaryReplicationInfo() (or the equivalent monitoring metric) reports current lag per secondary
  • A secondary with high, sustained lag is a real operational signal — often hardware, network, or write-volume related, worth investigating rather than ignoring
  • Lag directly bounds how stale a read using a secondary-inclusive read preference can be — larger lag, larger possible staleness

Command

text
rs.printSecondaryReplicationInfo() — reports each secondary's lag behind the primary

Replica lag is the time delay between the primary and a specific secondary applying a change — normally tiny, but the exact number that bounds how stale a secondary-routed read can be, and worth monitoring rather than assuming.

8.Why secondary reads can be stale

A secondary applies the primary's writes with a delay — replica lag — so a read routed there can return data that does not yet include the most recent write, even one made moments earlier by the same client. This is the concrete cost behind every read-preference decision that allows secondaries.

Key features

  • A write acknowledged on the primary is not instantly visible on every secondary — it becomes visible on each one only once that secondary's replication catches up
  • The classic symptom: a user updates something, then immediately reads it back and sees the old value, because the read landed on a lagging secondary
  • Read-your-own-writes consistency is not automatic across primary/secondary reads — it needs either reading from the primary, or a session-scoped causal consistency guarantee
  • The staleness window is bounded by current replica lag, which is why monitoring lag matters before relying on secondary reads for anything sensitive
  • Read concern "majority" does not fix this by itself — it guarantees the data will not roll back, not that it is the most recent write

Command

text
// Read-your-writes needed? Use readPref("primary"), or a session for causal consistency — secondaryPreferred alone does not guarantee it

A secondary read can return data that does not yet include a recent write, because it reflects wherever that secondary's replication currently is — for read-your-own-writes, use readPref("primary") or a shared session for causal consistency, not secondaryPreferred alone.

Remember

  • A replica set is several servers with the same data — one primary accepts writes, the rest replicate.
  • Secondaries stay in sync by tailing and replaying the primary's idempotent oplog.
  • An election picks a new primary by majority vote — a few seconds of write unavailability is expected, not a bug.
  • Read preference decides which member a read can reach; "Preferred" always means try-then-fallback.

Pro tip

  • For read-your-own-writes, use readPref("primary") or a shared session for causal consistency — not secondaryPreferred alone.
  • Monitor replica lag before relying on secondary reads for anything time-sensitive.

Next up

  • Replica Set Architecture
  • Sharding
  • Change Streams and Event-Driven Design

Sources

  • Replication — mongodb.com/docs/manual/replication/
  • Read preference — mongodb.com/docs/manual/core/read-preference/
  • Checked 2026-09-10

Spotted a mistake on this page? Tell us.