All articles
169 articles · updated weekly See our Tools
All articles
Comparisons

When to Use MongoDB: Does the Document Model Make Sense?

When to use MongoDB and when not to: concrete criteria for choosing between the document model and relational tables.

When to Use MongoDB: Does the Document Model Make Sense?
COVER · Comparisons

You reached for MongoDB because someone on the team said "rigid schemas slow the product down," modeled everything as nested documents, and three months later you're stacking $lookup on top of $lookup to stitch orders, customers, and payments back together. The feeling is familiar: you reinvented the JOIN, only slower and without transactional guarantees. The problem is rarely MongoDB. It's having picked the document model for data that is, at its core, relational.

The right question isn't "is MongoDB better than Postgres?" It's "is my data naturally a document or a web of relationships?" This guide answers that with concrete criteria, not slogans.

What a document actually is

In the relational model you split an entity across several normalized tables and reassemble it with JOINs at read time. In MongoDB you store the entity exactly as it's consumed: an order with its line items, shipping address, and a customer snapshot, all in a single JSON-like (BSON) document.

{
  "_id": "ord_8821",
  "customer": { "name": "Ana Lima", "email": "ana@ex.com" },
  "items": [
    { "sku": "KEY-01", "qty": 2, "price": 149.9 },
    { "sku": "MOU-03", "qty": 1, "price": 89.0 }
  ],
  "total": 388.8,
  "status": "paid"
}

MongoDB's golden rule is: data that's accessed together is stored together. If your screen shows the entire order at once, reading that document is a single trip to disk, no JOIN. That's where the document model shines — and it's exactly where most people misjudge the technology.

When documents make more sense

Documents win when the shape of the data and the access pattern conspire in your favor:

  • The entity is read and written as one block. Shopping cart, user profile, account settings, a post with embedded comments. You almost never want "just the items" without the order.
  • The schema varies between records. A product catalog where a TV has screen size and a t-shirt has a size label. In a relational store that becomes nullable columns or a generic attribute table (the dreaded EAV); in a document, each product carries only the fields it has.
  • The data evolves fast. Early in a product's life the schema changes weekly. Adding a field to some documents doesn't require an ALTER TABLE across millions of rows.
  • You need to scale horizontally. MongoDB's native sharding distributes documents by key across nodes — a more direct path than hand-rolled relational sharding.
  • The data arrives semi-structured. Events, logs, webhook payloads, telemetry — high-volume things that show up in irregular shapes.

Notice the pattern: every one of these has a clear aggregation boundary. The document is the natural unit of both reading and writing.

When documents get in the way (and tables win)

This is where the original mistake lives. The document model charges a steep price when the data is essentially a many-to-many web queried from different angles:

  • You need many JOINs across independent entities. If every query needs a $lookup linking separate collections, that's a strong signal the data is relational. JOINs exist in MongoDB, but they aren't the terrain it runs best on.
  • Transactions must be ACID across several entities. MongoDB has supported multi-document transactions since 4.0, but they carry cost and limits — it's not the design the engine is optimized for. Moving money between accounts is the classic case that calls for relational.
  • The same information is queried along multiple axes. A report crossing sales by region, by rep, and by product benefits from normalized tables and mature SQL. Duplicating that across documents becomes a consistency nightmare.
  • Compliance demands relational. Payment processors and financial regulators frequently only certify financial data in traditional RDBMS. That's less engineering and more regulation.

There's also a silent cost: to avoid JOINs you duplicate data (the customer snapshot inside every order, for instance). That uses more disk and creates the problem of keeping copies in sync when the original changes. If you caught yourself writing routines to propagate a customer name change across 40,000 documents, the model is wrong for that data.

Embed or reference: the decision that defines everything

Inside MongoDB itself lives the choice that most separates healthy projects from painful ones: embedding (nesting) versus referencing (by id, foreign-key style).

Embed when the relationship is containment and the child can't live alone: line items of an order, comments on a low-volume post. Reference when the sub-object is large, grows without bound, or is shared across multiple parents.

// Embedding — items live inside the order
db.orders.findOne({ _id: "ord_8821" })  // everything in 1 read

// Referencing — comments in their own collection
db.comments.find({ post_id: "post_42" }).limit(20)

MongoDB documents have a 16 MB limit. An ever-growing list — like the activity feed of a user active for years — can't be embedded; it will blow past the document size. That limit is, in practice, your wrong-modeling detector.

The choice isn't binary

Mature teams don't pick "MongoDB or Postgres" for the whole system. They pick per context: product catalog and sessions in documents, the financial ledger in relational. If you want the broader difference between the two database families — consistency, scalability, transaction models — read our comparison on relational vs NoSQL databases, which treats the decision at a more architectural level. This guide is the zoom-in on the document case specifically.

Postgres, by the way, has the JSONB type, which stores indexed documents. For a small slice of flexible data inside a mostly relational system, that often solves the problem without bringing a second database to operate.

Frequently asked questions

When should you use MongoDB instead of a relational database?

When the entity is read and written as one cohesive block, the schema varies between records, the data evolves fast, or you need simple horizontal scale. If your access pattern is "fetch the whole document by a key," the document model is direct and fast.

When should you NOT use MongoDB?

When the data is a many-to-many web queried from multiple angles, when you need firm ACID transactions across distinct entities, or when the domain (typically financial) requires RDBMS for compliance. If you're writing $lookup in nearly every query, the data is relational.

Does MongoDB use more disk space than a relational database?

Generally yes, because the document model tends to duplicate data to avoid JOINs — the customer snapshot in every order, for example. You trade disk space for read speed and for skipping JOINs. The real concern isn't the disk itself, it's keeping the copies consistent when the original changes.

Can you use MongoDB and a relational database in the same project?

Yes, and it's common. Use each database where it's strong: documents for self-contained, variable-schema entities; relational for the transactional core and cross-cutting reports. Postgres with JSONB is also a valid middle ground when the flexible portion is small.

What to take from this guide

The document model isn't "the future" or a "passing fad" — it's a choice about the shape of your data. Ask yourself: does my entity have a clear aggregation boundary, is it read as a block, and does the 16 MB limit give me room? If yes, documents will serve you well and spare you JOINs. If you find yourself rebuilding JOINs with $lookup, syncing copies by hand, or fighting transactions across collections, the signal is clear: that data wanted to be a table all along.

RD
Author
Rafael Duarte
Backend developer with a background in fintech and B2B SaaS — worked on teams that scaled APIs from zero to millions of requests. Carries enough production scars to hold strong opinions on tools, patterns and architecture decisions. Not an academic: he read the UUID RFC when he had to choose between v4 and v7 for a write-heavy table.
View profile