MongoDB#
Document Tunable consistency Schema-flexible
What it is#
MongoDB is a document database: instead of rows in tables, it stores JSON-like documents (BSON, a binary superset of JSON) in collections. There's no required schema, related data is usually embedded in one document rather than joined across tables.
How it works under the hood#
Documents live in collections, collections live in databases. Internally, MongoDB stores BSON on disk via the WiredTiger storage engine, which handles MVCC-style concurrency and compression. Replication happens via replica sets: one primary takes writes, secondaries replicate asynchronously via an operation log (the oplog), and can take over automatically if the primary goes down.
Embedding vs referencingThe core modeling decision in MongoDB.
The core modeling decision in MongoDB. Embed related data in one document when it's read together and doesn't grow unbounded (an order and its line items). Reference by ID when data is shared across many parents or grows without limit (a user referenced by thousands of posts). Getting this wrong is the most common source of MongoDB performance problems.
Setting it up#
docker run --name mongo -p 27017:27017 -d mongo:7
brew tap mongodb/brew
brew install mongodb-community
brew services start mongodb-community
1. Create a free cluster at mongodb.com/atlas
2. Add your IP to the network access list
3. Grab the connection string and use it directly
Your first queries#
db.users.insertOne({ email: "ada@example.com", createdAt: new Date() });
db.orders.find({ customerId: 42 }).sort({ createdAt: -1 }).limit(10);
db.orders.aggregate([
{ $match: { status: "paid" } },
{ $group: { _id: "$customerId", total: { $sum: "$amount" } } }
]);
Notable functionality#
Multi-stage data processing, similar in spirit to SQL's GROUP BY but far more composable
Runs inside the database, close to the data
Can replace a surprising amount of application-side data munging
Documents in the same collection can have different shapes
Schema validation rules are optional, not mandatory
Great for evolving data models early in a product's life
Tunable consistency#
Read/write concern | What it means |
|---|---|
| Waits for acknowledgment from a majority of replica set members, giving strong durability at the cost of more latency |
| Acknowledged by the node handling the request only, the fastest option and the least durable |
| Strongest guarantee, reads reflect all previously completed writes |
Note
This is a per-query decision, not a database-wide setting, which is both the power and the danger of MongoDB. Pick loose consistency without noticing, and you can get surprising results under load.
In production#
// See what's actually slow right now
db.currentOp({ "secs_running": { "$gt": 3 } });
Sharding distributes collections across multiple replica sets by a shard key you choose. Choosing a bad shard key (like a monotonically increasing timestamp) creates hot shards that absorb all the write traffic while others sit idle.
Warning
Unbounded array growth inside a single document is a classic MongoDB production incident. A document has a 16MB hard limit, and an ever-growing embedded array (like "all comments on this post") will eventually hit it.
Pros and cons#
Natural fit for nested, document-shaped data
Schema flexibility speeds up early development
Horizontal scaling (sharding) is a first-class, built-in feature
Aggregation pipeline is genuinely powerful
No joins in the relational sense, denormalization is the norm
Easy to accidentally pick a weak consistency level
Schema flexibility can become schema chaos without discipline
Multi-document transactions exist but are heavier than in an RDBMS
When to reach for it#
Good fits: content management systems, catalogs with wildly varying product attributes, event and log storage, and applications where the data model is still actively evolving and a rigid schema would slow the team down.
When it's not the right fit#
Data that's naturally relational and needs real joins across many entities
Workloads requiring strict, always-on strong consistency without per-query tuning
Small, stable schemas where a relational database's guarantees are simply better default behavior
consistency-tradeoffs-at-scale for more on what tunable consistency actually costs you.