MongoDB Production Engineering
MongoDB's flexible schema doesn't remove the need for schema design — it just moves the cost from migration scripts to query-time index misses and oversized documents. This section covers schema design, index strategy, aggregation performance, replication, and sharding as they actually behave under production load.
Schema Design
MongoDB's flexibility is a tool, not an excuse — the shape of your documents still determines your application's performance ceiling.
Model for your queries
Design documents around how data is read, not just how it's conceptually related — MongoDB rewards read-optimized, denormalized shapes.
Schema validation
$jsonSchema validation rules enforce required fields and types at the database level, without giving up per-document flexibility entirely.
Index Optimization
The right index turns a multi-second query into a sub-millisecond one. The wrong index just slows down every write.
Compound index field order
An index on { customerId: 1, createdAt: -1 } serves queries filtering on customerId alone, or customerId + createdAt range — but not createdAt alone. Order matters (the ESR rule: Equality, Sort, Range).
Partial indexes
{ partialFilterExpression: { status: 'pending' } } — index only the documents a query actually needs, keeping the index small.
Covered queries
If every field a query needs is present in the index itself, MongoDB can answer without fetching the document at all.
Aggregation Performance
An aggregation pipeline can be as fast as an indexed query or as slow as scanning the whole collection, depending on stage order.
$match early, $match often
Placing $match (and $sort, when it can use an index) as early as possible lets MongoDB use indexes and shrinks the working set for every later stage.
$lookup cost
A $lookup join scans the foreign collection per input document unless it can use an index on the foreign field — always index the field a $lookup joins on.
explain()
explain() shows the plan MongoDB chose and, in executionStats mode, how many documents it actually examined.
db.orders.find({ customerId: 42 }).explain('executionStats')totalDocsExamined vs nReturned
A big gap between documents examined and documents returned is the #1 sign a query needs a better index.
winningPlan.stage
COLLSCAN means no usable index was found; IXSCAN means an index narrowed the search before fetching documents.
Replication
Replica sets are how MongoDB survives a machine dying and how it scales reads horizontally.
Read preference
primary, primaryPreferred, secondary, secondaryPreferred, or nearest — controls which member(s) can serve a read, trading recency for read scalability.
Oplog sizing
The oplog is a capped collection — if it's too small, a secondary that falls behind (e.g. after maintenance) may not be able to catch up and needs a full resync.
Read & Write Concerns
Write concern controls durability guarantees per write; read concern controls consistency guarantees per read — both are configurable, not fixed platform-wide.
w: majority
Waits for a majority of voting replica set members to acknowledge before confirming a write — survives a primary failure immediately after the write. It is the implicit default in MongoDB 5.0+ (with documented exceptions, such as some arbiter-containing topologies, and configurable cluster-wide defaults); earlier versions default to w: 1.
readConcern: majority
Guarantees a read only returns data acknowledged by a majority — avoiding reads of data that could later be rolled back after a failover.
Monitoring
MongoDB exposes rich operational data through server status and profiling — the discipline is watching it before it becomes an incident.
Database Profiler
Logs slow operations above a configurable threshold — the first place to look for a specific slow query in production.
serverStatus / currentOp
Live view of connections, memory, and in-flight operations — the equivalent of Postgres' pg_stat_activity.
Replication lag metrics
rs.printSecondaryReplicationInfo() shows how far behind each secondary is — critical for read-preference correctness and failover readiness.
Common Production Issues & Debugging
A handful of failure modes account for most MongoDB incidents — and a repeatable order of operations turns a stressful incident into a checklist.
Unbounded array growth
An embedded array that grows without limit (e.g. comments on a post) eventually approaches the 16 MB document size limit and slows every read/write of that document.
Missing shard key in queries
Scatter-gather queries that hit every shard, when a targeted query using the shard key would have hit just one.
Oplog too small for maintenance windows
A secondary taken down for maintenance falls off the back of the oplog and requires a full, expensive resync instead of catching up.
- Check the profiler and currentOp for long-running or blocked operations first.
- Run explain('executionStats') on the slow query — look for COLLSCAN and large totalDocsExamined vs nReturned gaps.
- Check replication lag if reads use a non-primary read preference.
- Check shard targeting — is the query using the shard key, or scatter-gathering?
- Only then consider a schema or index change — never guess before measuring.