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 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.
# Start mongod with --replSet rs0
mongosh --eval 'rs.initiate({ _id: "rs0", members: [{ _id: 0, host: "localhost:27017" }] })'
# Verify status
mongosh --eval 'rs.status()'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.
// 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.
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...
});