R
Rishtaara
MongoDB Fundamentals
Lesson 34 of 40Article18 min

Replication & Replica Sets

Replication copies your data to multiple MongoDB servers so a single hardware failure does not take down your app. A replica set is a group of mongod instances that maintain the same data set — one primary and one or more secondaries.

Why replication matters

Replication copies your data to multiple MongoDB servers so a single hardware failure does not take down your app. A replica set is a group of mongod instances that maintain the same data set — one primary and one or more secondaries.

Replication also enables zero-downtime maintenance (rolling upgrades), disaster recovery, and read scaling by directing read traffic to secondaries.

Real-life example: A replica set is like keeping photocopies of important files in two office cabinets. If one cabinet floods, you still have the other copy — and colleagues can read from either cabinet.

Replica set — primary, secondaries, oplog

Replica set members — primary, secondary, arbiter

  • Primary — receives all write operations. Only one primary exists at a time.
  • Secondary — replicates the primary's oplog (operation log). Can serve reads if read preference allows.
  • Arbiter — participates in elections but holds no data. Lightweight tie-breaker for even-numbered clusters (avoid in production if possible — use an odd count of data-bearing nodes instead).
  • Hidden / delayed secondaries — for analytics snapshots or point-in-time recovery; never receive application reads.
Initiate a single-node replica set (local dev)
# Start mongod with --replSet rs0
mongosh --eval 'rs.initiate({ _id: "rs0", members: [{ _id: 0, host: "localhost:27017" }] })'

# Verify status
mongosh --eval 'rs.status()'
Three-member replica set config sketch
rs.initiate({
  _id: "rs0",
  members: [
    { _id: 0, host: "mongo1.example.com:27017", priority: 2 },
    { _id: 1, host: "mongo2.example.com:27017", priority: 1 },
    { _id: 2, host: "mongo3.example.com:27017", priority: 1 }
  ]
})

Deployment basics

Production replica sets use at least three data-bearing nodes across availability zones — or two nodes plus an arbiter only as a budget compromise. MongoDB Atlas handles replica set deployment, backups, and monitoring automatically.

Set electionTimeoutMillis and priority to control failover behavior. Use keyFile authentication so only cluster members can join the set.

Real-life example: Deploying three nodes in different data centers is like having branch offices in three cities — a flood in one city does not stop the whole company.

  • Odd number of voting members prevents split-brain during network partitions.
  • Write concern "majority" waits until a write is replicated to a majority before acknowledging.
  • Read concern "majority" returns data that will not be rolled back after a failover.
  • Atlas M10+ clusters include automated backups with point-in-time restore.

Read/write semantics and read preference

By default, drivers send writes to the primary and reads to the primary too. You can change read preference to distribute read load — but secondary reads may be slightly stale (eventual consistency).

Real-life example: Read preference "secondary" is reading yesterday's newspaper from the archive room — fine for analytics, wrong for breaking news (financial balances).

  • primary (default) — always read from primary; strongest consistency.
  • primaryPreferred — primary if available, else secondary.
  • secondary — only secondaries; fails if none available.
  • secondaryPreferred — secondary if available, else primary.
  • nearest — lowest-latency node; good for geo-distributed apps.
Connection string with read preference
// Analytics reads from secondaries; writes still go to primary
const uri =
  "mongodb://user:pass@host1,host2,host3/rishtaara?replicaSet=rs0&readPreference=secondaryPreferred";

await mongoose.connect(uri);

// Per-query override
const stats = await Order.find({ status: "completed" })
  .read("secondary")
  .limit(1000);

Change streams — brief intro

Change streams let your application watch a collection, database, or entire cluster for insert, update, replace, and delete events in real time. They require a replica set or sharded cluster.

Use cases: invalidate caches, sync to Elasticsearch, trigger notifications, build event-driven microservices.

Real-life example: Change streams are a news ticker — every time data changes in MongoDB, your app gets a push notification instead of polling every few seconds.

Tip: Change streams resume from a token — store resumeAfter on disconnect so you never miss events during restarts.
Watch a collection for changes
const changeStream = db.orders.watch([
  { $match: { "operationType": { $in: ["insert", "update"] } } }
]);

changeStream.on("change", (event) => {
  console.log("Order changed:", event.documentKey._id, event.operationType);
  // Invalidate cache, send webhook, update search index...
});