Intro
Running MongoDB in production is straightforward if you standardize a few decisions and script the routine work. This guide gives you a practical checklist with copy-paste examples for:
- Configuration and replica sets
- Security hardening
- Monitoring and troubleshooting
- Backups and reliable restores
- Maintenance routines
- Upgrades and rollouts
- Common pitfalls to avoid
Examples use mongosh, systemd, and Node.js/Express so you can adapt them quickly.
---
Workflow Overview
A clear, repeatable workflow keeps production stable:
- Plan
- Define SLOs: p95 latency, availability, RPO/RTO.
- Capacity: working set vs RAM, IOPS, growth rate.
- Configure
- Apply a baseline mongod.conf and systemd unit.
- Use a 3-node replica set minimum.
- Secure
- Enable authorization, create RBAC users, require TLS.
- Restrict network access and rotate secrets.
- Connect apps
- Safe driver settings: pooled connections, timeouts, majority writes.
- Observe
- Dashboards and alerts: replication lag, cache, slow ops, disk.
- Protect data
- Logical + snapshot backups. Practice restores.
- Maintain
- Health checks, index reviews, log rotation, targeted validation.
- Upgrade
- Rolling upgrades with backups and feature compatibility gating.
- Iterate
- Start small, measure, expand.
---
Configuration Baseline
Use consistent, version-controlled config and OS settings.
Example /etc/mongod.conf:
storage:
dbPath: /var/lib/mongo
journal:
enabled: true
wiredTiger:
engineConfig:
cacheSizeGB: 4
net:
port: 27017
bindIp: 127.0.0.1,10.0.0.10
security:
authorization: enabled
replication:
replSetName: rs0
setParameter:
diagnosticDataCollectionEnabled: true
Example systemd unit /etc/systemd/system/mongod.service:
[Unit]
Description=MongoDB Database Server
After=network.target
[Service]
User=mongodb
Group=mongodb
ExecStart=/usr/bin/mongod --config /etc/mongod.conf
LimitNOFILE=64000
Restart=on-failure
Type=notify
[Install]
WantedBy=multi-user.target
Replica set init (replace hosts):
mongosh --host 10.0.0.10 --eval 'rs.initiate({_id:"rs0", members:[{_id:0, host:"10.0.0.10:27017"},{_id:1, host:"10.0.0.11:27017"},{_id:2, host:"10.0.0.12:27017"}]})'
OS and filesystem notes
- Ensure swappiness is low for database nodes.
- Use XFS or ext4 with noatime if appropriate.
- Provision IOPS headroom; avoid noisy neighbors.
- Set vm.max_map_count and file descriptors high enough for workload.
---
Security Hardening
- Enable auth and create users
mongosh --host primary-host <<'EOF'
use admin
db.createUser({
user: "siteRootAdmin",
pwd: "REDACTED-STRONG-PASSWORD",
roles: [ { role: "root", db: "admin" } ]
})
use appdb
db.createUser({
user: "appUser",
pwd: "REDACTED-App-Pass",
roles: [ { role: "readWrite", db: "appdb" } ]
})
EOF
- Require TLS
# In mongod.conf
net:
tls:
mode: requireTLS
certificateKeyFile: /etc/ssl/mongo/server.pem
CAFile: /etc/ssl/mongo/ca.pem
- Network controls
- Bind to explicit IPs only.
- Restrict ingress to app and admin subnets.
- Use separate security groups for client and replication traffic if possible.
- Secrets and keys
- Rotate DB passwords and TLS certs regularly.
- Avoid storing credentials in app repos; use environment variables or a secrets manager.
---
Observability and Monitoring
Key signals to watch
- Replication: rs.status(), replication lag < your RPO.
- WiredTiger cache: cache used vs configured; evictions rising with high latency signals memory pressure.
- Connections: spikes can indicate leaks or storms.
- Operation mix: insert/update/delete/query rates.
- Queues and locks: active readers/writers, lock percentage during spikes.
- Disk: IOPS, latency, free space, checkpoint times.
- Slow queries: capture and fix top offenders.
Quick tools
# High-level counters
mongostat --rowcount 5
# Per-collection activity
mongotop 5
Server-side profiling (use sparingly)
// In mongosh, enable slow op threshold 200ms
db.setProfilingLevel(1, { slowms: 200 })
// Later, disable
db.setProfilingLevel(0)
Alert suggestions
- Replication lag > 10s (tune to your RPO).
- Cache dirty/used approaching 90% with rising latency.
- Disk free < 15% or filesystem almost full.
- Connections near pool limit.
- Oplog window < restore window requirement.
Logging
- Keep log files on separate volume from data if possible.
- Rotate with logRotate and system logrotate.
---
Backups and Restore
Combine logical and snapshot strategies.
- Logical dumps for portability
# Replica set-aware logical dump with oplog for PITR window
mongodump \
--uri "mongodb://appUser: REDACTED@rs0-1, rs0-2, rs0-3/admin?replicaSet=rs0" \
--out /backups/$(date +%F) \
--oplog
Restore test
mongorestore \
--uri "mongodb://restoreUser: REDACTED@localhost:27017/admin" \
--dir /backups/2026-07-10 \
--oplogReplay \
--drop
- Filesystem snapshots for speed (on a secondary)
# Quiesce the secondary for a clean snapshot
mongosh --host rs0/secondary-host --eval 'db.fsyncLock()'
# Create and mount LVM snapshot (example; adapt to your storage)
lvcreate -L 20G -s -n mongo-data-snap /dev/vg0/mongo-data
mount -o ro /dev/vg0/mongo-data-snap /mnt/mongo-snap
# Copy snapshot off-host
rsync -aH --numeric-ids /mnt/mongo-snap/ /backup-target/mongo/
# Cleanup
umount /mnt/mongo-snap
lvremove -f /dev/vg0/mongo-data-snap
mongosh --host rs0/secondary-host --eval 'db.fsyncUnlock()'
Backup policy checklist
- Define RPO and RTO targets.
- Store backups offsite and encrypt at rest.
- Keep at least one recent full backup verified by restore.
- Automate restore tests (e.g., nightly into a disposable environment) and validate counts and checksums.
---
Maintenance and Routine Ops
Weekly
- Review slow queries; add or adjust indexes.
- Check replication lag trends and oplog window.
- Verify backup job success and last tested restore timestamp.
Daily
- Inspect dashboards for error spikes and storage growth.
- Rotate logs if needed.
Monthly
- Validate a subset of collections:
// Sample validation; avoid heavy full-db validate during peak
db.getCollectionNames().slice(0,5).forEach(c => printjson(db.getCollection(c).validate({ full: false })))
Index care
- Prefer compound indexes that match query patterns.
- Drop unused indexes after verifying via usage stats.
Operational safety
- Avoid running compact or full validation during peak usage.
- Schedule heavy tasks with rate limits.
---
Upgrades and Rollouts
Prepare
- Read release notes for breaking changes.
- Verify drivers are compatible.
- Back up and test a restore.
Rolling upgrade (replica set)
- Upgrade a secondary
# Stop secondary, upgrade binary via your package method, start
systemctl stop mongod
# ... upgrade binaries ...
systemctl start mongod
# Wait for SECONDARY and full replication
- Repeat for all secondaries
- Step down primary and upgrade it
mongosh --host primary --eval 'rs.stepDown(60)'
# Upgrade and restart primary node
- Feature compatibility version (after all nodes upgraded)
// Set FCV to the new version after stability checks
db.adminCommand({ setFeatureCompatibilityVersion: "X.Y" })
Observability during upgrade
- Watch replication lag, elections, and client errors.
- Pause between nodes to ensure stability.
Rollback plan
- If errors rise, stop and roll back upgraded nodes to previous version.
---
Local Pilot Plan
Start small, measure, then expand.
Scope
- A 3-node test replica set (containers or VMs).
- One Express API with 2-3 endpoints.
- Minimal dashboards for core metrics.
- One backup job and one automated restore test.
Steps
- Provision
- Launch 3 nodes and apply the baseline mongod.conf and systemd.
- Initiate the replica set.
- Secure
- Create admin and app users, enable TLS.
- Connect an Express API
// app.js
const express = require('express');
const { MongoClient } = require('mongodb');
const uri = 'mongodb://appUser: [email protected],10.0.0.11,10.0.0.12/appdb?replicaSet=rs0&tls=true';
const client = new MongoClient(uri, {
maxPoolSize: 50,
minPoolSize: 5,
waitQueueTimeoutMS: 5000,
serverSelectionTimeoutMS: 5000,
socketTimeoutMS: 20000,
retryWrites: true,
w: 'majority',
wtimeoutMS: 5000
});
const app = express();
app.use(express.json());
app.get('/healthz', async (req, res) => {
try {
await client.db('admin').command({ ping: 1 });
res.status(200).send('ok');
} catch (e) {
res.status(500).send('not-ok');
}
});
app.post('/items', async (req, res) => {
try {
const r = await client.db('appdb').collection('items').insertOne(req.body);
res.status(201).json({ id: r.insertedId });
} catch (e) {
res.status(500).json({ error: 'insert_failed' });
}
});
(async () => {
await client.connect();
app.listen(3000, () => console.log('API on :3000'));
})();
- Back up and restore
- Run mongodump with --oplog.
- Restore into a throwaway MongoDB and run a quick data validation.
- Failure drills
- Kill the primary and confirm failover < SLO.
- Throttle disk to simulate I/O pressure and observe latencies.
Pilot success criteria
- p95 API latency within target under nominal load.
- Automatic failover time within target.
- Successful restore completed within RTO and data validated.
---
Common Production Pitfalls
- No auth or TLS: enable authorization and require TLS.
- Single-node deployments: use at least 3 nodes for high availability.
- Unsafe writes: avoid w:1 without journaling; prefer w: "majority" and journaled writes.
- Missing indexes: slow queries and high CPU; add indexes for filter and sort fields.
- Huge documents: MongoDB has a document size limit; redesign schema or use GridFS where needed.
- Hot primary: all reads on primary; consider appropriate read preferences for read-heavy workloads.
- Small oplog: replication falls behind and point-in-time recovery window shrinks; size oplog based on write rate.
- Untested backups: a backup you have not restored is not proven; schedule restore tests.
- Uncontrolled growth: TTL indexes for ephemeral data; archive old collections.
- Upgrades without FCV planning: set and verify feature compatibility at the right time.
Quick checks
# Auth on?
mongosh --eval 'db.runCommand({ connectionStatus: 1 })'
# Replication healthy?
mongosh --eval 'rs.status()'
# Slow ops?
mongosh --eval 'db.getSiblingDB("admin").system.profile.find().sort({ts:-1}).limit(5)'
---
Conclusion
You now have a practical, end-to-end checklist to run MongoDB in production: a hardened configuration, strong security, actionable monitoring, reliable backups with tested restores, safe maintenance routines, and controlled upgrades. Start with the local pilot, measure failover and restore times, fix gaps, and then scale the same patterns to staging and production.