A single database server is a single point of failure. If its disk dies, data is lost; if it restarts for an update, the application goes down. MongoDB solves this with replication: a replica set is a group of servers, usually three, that hold copies of the same data.
One member is the primary, which receives all writes. The others are secondaries, which continuously copy the primary's changes from its oplog (operations log). If the primary becomes unavailable, the remaining members hold an election and promote a secondary to primary, usually within seconds. Applications using the official drivers reconnect to the new primary automatically, and retryable writes repeat an interrupted write once.
Replica sets also let you choose trade-offs. A write concern decides how many members must confirm a write before it's acknowledged, which controls durability. A read preference decides which members can serve reads. In this lesson you'll set up and inspect a replica set, see what happens during failover, and choose write concerns and read preferences sensibly. Every Atlas cluster is a replica set, and every production deployment should be one.
How a replica set works
- The primary accepts writes and records each change in its oplog, a special capped collection.
- Secondaries replay the oplog to stay in sync. The delay between the primary and a secondary is replication lag.
- Members send heartbeats every two seconds. If the primary is unreachable for about 10 seconds, an election chooses a new one.
- An election needs a majority of voting members. With three members, the set survives the loss of one; with five, it survives two. That's why replica sets have an odd number of voting members.
- Hidden and delayed members hold copies for backups or analytics without serving application reads.
Setting up and inspecting
mongod --replSet rs0 --port 27017 --dbpath /data/a
mongod --replSet rs0 --port 27018 --dbpath /data/b
mongod --replSet rs0 --port 27019 --dbpath /data/crs.initiate({
_id: 'rs0',
members: [
{ _id: 0, host: 'db1.example.internal:27017' },
{ _id: 1, host: 'db2.example.internal:27018' },
{ _id: 2, host: 'db3.example.internal:27019' }
]
})
rs.status() // members, their states and how far behind they are
rs.conf() // the configuration
rs.stepDown() // ask the primary to step down, for maintenanceApplications connect with all members and the set name: mongodb://db1:27017,db2:27018,db3:27019/?replicaSet=rs0. Atlas gives you an mongodb+srv:// string that does the same.
Write concern, read preference and read concern
| Setting | Options | Meaning |
|---|---|---|
Write concern w | 1, 'majority', a number | How many members must confirm a write |
Journal j | true | Wait until the write is on disk |
| Read preference | primary, primaryPreferred, secondary, secondaryPreferred, nearest | Which members may serve reads |
| Read concern | local, majority, snapshot | Whether reads can see data that might be rolled back |
The default write concern is majority: a write is acknowledged only when most members have it, so it survives a failover. Reading from secondaries spreads load but may return slightly stale data, so use it for reports and analytics, not for reading back something a user just saved.
MongoDB Operations Syntax
Replica set commands
rs.initiate({ _id: 'rs0', members: [{ _id: 0, host: 'a:27017' }, { _id: 1, host: 'b:27017' }, { _id: 2, host: 'c:27017' }] })
rs.status().members.map(m => `${m.name} ${m.stateStr}`)
rs.add('d:27017')
rs.stepDown()
db.orders.insertOne(doc, { writeConcern: { w: 'majority', wtimeout: 5000 } })
db.orders.find().readPref('secondaryPreferred')
db.getMongo().setReadPref('nearest')
// mongodb://a:27017,b:27017,c:27017/?replicaSet=rs0&readPreference=secondaryPreferredMongoDB Operations Summary
- A replica set is a group of servers holding copies of the same data: one primary, several secondaries.
- Secondaries replay the primary's oplog; elections pick a new primary automatically if it fails.
- Use an odd number of voting members, usually three, so a majority can always be reached.
- Write concern majority makes writes survive failover; read preferences can send reads to secondaries.
- Drivers reconnect after failover and retry writes once; every production deployment should be a replica set.
MongoDB Operations Examples
Each example shows the code, the output it produces and what each part does.
Inspecting a replica set
rs.status().set
rs.status().members.map(m => `${m.name} ${m.stateStr} health ${m.health}`)
rs.conf().members.length
db.hello().isWritablePrimary
db.getSiblingDB('local').oplog.rs.find({ op: 'i' }, { op: 1, ns: 1, _id: 0 }).sort({ $natural: -1 }).limit(1)rs0
[
'db1.example.internal:27017 PRIMARY health 1',
'db2.example.internal:27018 SECONDARY health 1',
'db3.example.internal:27019 SECONDARY health 1'
]
3
true
[ { op: 'i', ns: 'shop.orders' } ]Line-by-line explanation
- Line 1The replica set's name, which must match the replicaSet option in connection strings.
- Line 2One primary and two healthy secondaries.
- Line 4hello reports whether the member you're connected to accepts writes.
- Line 5The oplog records every change; here the latest insert went into shop.orders.
Write concerns and read preferences
db.orders.insertOne({ _id: 9001, total: 59.9 }, { writeConcern: { w: 'majority', wtimeout: 5000 } })
db.orders.insertOne({ _id: 9002, total: 12.5 }, { writeConcern: { w: 1 } })
db.orders.find({ _id: 9001 }).readPref('primary').toArray().length
db.reports.find().readPref('secondaryPreferred').limit(1).toArray().length
db.getMongo().getReadPrefMode(){ acknowledged: true, insertedId: 9001 }
{ acknowledged: true, insertedId: 9002 }
1
1
primaryLine-by-line explanation
- Line 1majority waits until most members have the write, so it survives a failover; wtimeout stops it waiting forever.
- Line 2w: 1 only waits for the primary: faster, but the write could be lost if the primary fails before replicating.
- Line 4Reading from the primary always sees the latest acknowledged writes.
- Line 5Reports can read from a secondary to spread the load, accepting slightly stale data.
- Line 6The default read preference is primary.
What happens during failover
// before maintenance
rs.status().members.filter(m => m.stateStr === 'PRIMARY').map(m => m.name)
rs.stepDown(60).ok
// about ten seconds later, after the election
rs.status().members.filter(m => m.stateStr === 'PRIMARY').map(m => m.name)
rs.status().members.find(m => m.name === 'db1.example.internal:27017').stateStr[ 'db1.example.internal:27017' ]
1
[ 'db2.example.internal:27018' ]
SECONDARYLine-by-line explanation
- Line 2db1 is the current primary.
- Line 3stepDown asks it to become a secondary for 60 seconds, as you'd do before patching a server.
- Line 5An election has made db2 the primary; applications using drivers reconnect automatically.
- Line 6The old primary keeps running as a secondary and catches up from the oplog.
Common MongoDB Operations Mistakes
Running production on a single server
mongod --dbpath /data/db # one disk failure loses everythingmongod --replSet rs0 --dbpath /data/db # on three servers, then rs.initiate(...)An even number of voting members
// two data centres with two members each: if the link between them fails, neither side has a majority// three voting members (or five), ideally spread over three locationsReading your own writes from a secondary
db.profiles.updateOne({ _id: me }, { $set: { name: 'Ada' } })
db.profiles.find({ _id: me }).readPref('secondary') // may still show the old namedb.profiles.find({ _id: me }) // read from the primary after writingMongoDB Operations in Real Projects
Replica sets in production
Atlas clusters are three-member replica sets by default, spread across availability zones, and Atlas handles elections, patching and monitoring. Self-managed teams run replica sets with members in different racks or zones, monitor replication lag, and use hidden or delayed members for backups and analytics. Applications rely on the drivers' automatic failover and retryable writes, so routine maintenance causes no visible downtime.
MongoDB Operations FAQ
How many members does a MongoDB replica set need?
Three voting members is the usual minimum for production, because a majority, two of three, can still elect a primary when one member fails. A single-member replica set is fine for development and enables features such as transactions and change streams. Avoid an even number of voting members, since it adds cost without surviving more failures.
Can I write to a secondary in MongoDB?
No. Only the primary accepts writes; a write sent directly to a secondary fails with a "not primary" error. Drivers connected with a replica set connection string always send writes to the current primary and find the new one after an election, so applications don't have to track it themselves.
What is the difference between replication and sharding in MongoDB?
Replication keeps full copies of the same data on several servers for high availability and data safety. Sharding splits data across several replica sets so that each one holds only part of it, which increases total storage and write capacity. Every production deployment uses replication; only very large or write-heavy ones need sharding as well.
How big is the MongoDB oplog?
By default, the WiredTiger oplog uses 5% of free disk space, with a minimum of 990 MB and a maximum of 50 GB. What really matters is the oplog window: how many hours of changes it holds. A secondary that falls further behind than that window can't catch up and must be resynced, so check it with rs.printReplicationInfo().
What is an arbiter in a MongoDB replica set?
An arbiter is a member that votes in elections but holds no data, so it's cheap to run. It can turn two data-bearing members into an odd-numbered set, but it can't help acknowledge majority writes, so writes can stall if a data-bearing member fails. Three data-bearing members are the safer choice where possible.
MongoDB Operations Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Complete the write concern so the write survives a failover.
db.orders.insertOne(order, { writeConcern: { w: '' } })
Which member of a replica set accepts writes?
How do secondaries stay in sync with the primary?
Why use an odd number of voting members?
What's the risk of reading from secondaries?
MongoDB Operations Quiz
5 questions to check what you learned.
What is a replica set?
- A backup file
- A group of MongoDB servers holding copies of the same data
- A sharded collection
- A set of indexes
What happens when the primary fails?
- The database is read-only forever
- All data is lost
- The remaining members elect a new primary, usually within seconds
- An admin must manually copy data
Which write concern is the default in modern MongoDB?
- w: 0
- w: 1
- w: 'all'
- w: 'majority'
What does rs.stepDown() do?
- Asks the primary to step down so another member is elected
- Deletes the replica set
- Removes a secondary
- Stops replication
What are retryable writes?
- Driver behaviour that automatically retries a write once after a failover or network error
- Writes that never fail
- Writes saved to a queue
- Transactions