MongoDB Engineering Insights
MongoDB's document model removes join-time schema rigidity but shifts the cost to query-shape discipline and index planning. This section covers the design decisions, trade-offs, and mistakes that come up most often once a MongoDB schema has to survive real traffic.
Why MongoDB Uses Documents
The alternative to documents is normalized rows and joins. MongoDB's designers bet that most applications think in objects, not joined tables.
A relational schema optimizes for eliminating duplication and guaranteeing consistency via constraints. A document model optimizes for matching the application's in-memory object shape, so reads need no assembly step across tables.
Embedding vs Referencing
Every relationship in a document model is a choice: embed the related data, or reference it by id in a separate collection.
Embed when the related data is read together with the parent almost every time and doesn't grow unboundedly (e.g. an address on a user). Reference when the data is large, shared across many parents, or updated independently and often (e.g. a product referenced by thousands of orders).
MongoDB vs PostgreSQL
Both are mature, production-grade databases — the differences show up in schema flexibility, consistency guarantees, and how they each scale.
Schema
MongoDB is flexible by default, opt into validation; PostgreSQL is strict by default, opt into flexibility (jsonb columns).
Joins
PostgreSQL's JOIN is a first-class, highly optimized operation; MongoDB's $lookup exists but is generally more expensive and less central to typical usage.
Horizontal scaling
MongoDB has native sharding built into the core product; PostgreSQL requires extensions (Citus) or application-level sharding for the same.
Transactions
PostgreSQL's multi-row, multi-table transactions have been core since day one; MongoDB added multi-document ACID transactions later, and they carry a performance cost relative to single-document writes.
Schema Design Trade-offs
MongoDB schema design pulls in opposite directions depending on whether reads or writes dominate.
A read-heavy workload wants more embedding and denormalization — fewer round trips per read. A write-heavy workload with shared, frequently-changing data wants more referencing — fewer places to update the same fact. Most real systems land somewhere in between, driven by measured access patterns rather than a-priori preference.
Common Mistakes
The same handful of mistakes account for most avoidable MongoDB pain.
Unbounded embedded arrays
Growing an array indefinitely inside a document instead of moving it to its own referenced collection once it's clearly unbounded.
Missing shard key in queries
Writing queries that don't include the shard key on a sharded collection, forcing expensive scatter-gather operations.
No schema validation at all
Treating 'flexible schema' as 'no schema' — inconsistent field names and types creep in and become a runtime bug source.
Ignoring write concern for critical data
Relying on the default write concern for financial or otherwise critical writes without checking what it is: the default is w:majority in MongoDB 5.0+ (with documented exceptions, such as some arbiter-containing topologies, and cluster-wide defaults can be configured), but w:1 in earlier versions. State w:majority explicitly where durability matters.
Frequently Asked Questions
Does MongoDB support transactions?
Yes — multi-document ACID transactions are supported across a replica set or sharded cluster, though single-document writes remain the fastest, atomic-by-default path.
Can MongoDB do joins?
Yes, via the $lookup aggregation stage — but it's generally more expensive than an equivalent SQL JOIN and best used sparingly, on indexed fields.
Is MongoDB good for analytics?
The aggregation pipeline handles moderate analytical workloads well; for very large-scale analytics, many teams still pair MongoDB with a dedicated warehouse.
Real-world Architectures
A few architecture shapes recur across almost every serious MongoDB deployment.
- A 3-member replica set per environment, with automatic failover — no external orchestrator required.
- Sharding introduced only once write throughput or storage genuinely exceeds a single replica set's capacity.
- Read preference tuned per use case — primary for critical reads, secondaryPreferred for analytics dashboards.
- Schema validation ($jsonSchema) enforced on collections where correctness matters, even though the database itself stays flexible.
- $indexStats and the profiler reviewed regularly to prune unused indexes and catch slow queries before they become incidents.