Where documents genuinely win, and where it is fashion
This module taught MongoDB fairly and in depth. This lesson is the judgement the whole thing was building toward: when is a document database the right choice, and when did somebody pick it because it was fashionable?
The honest answer matters because "just use MongoDB" was, for about a decade, the default advice to a generation of developers — and for a large fraction of them it was wrong, and they found out expensively. You should be able to make this call on evidence, not on which database has the nicer marketing.
Where documents genuinely win
Real cases, where a document database is the better engineering choice, not merely a workable one.
Content management. A CMS, a blog, a documentation site. A page is a self-contained document with a title, body, metadata, and a nested block structure that varies by page type. You read the whole page at once, you rarely query across pages relationally, and the shape differs from page to page. This is the document model's home.
Product catalogues with varied attributes. A marketplace where a book, a mobile phone and a sofa have almost no attributes in common. Relationally this is a sparse wide table or a mess of type-tables; as documents each product carries its own fields naturally, and you query within a category where the shape is consistent.
Event and activity logs. Append-mostly, self-contained events with a payload whose shape depends on the event type. You write a lot, read by time or type, and rarely need to join. (Though at serious scale a time-series database, module 12, beats both.)
Real-time and per-user state. Game state, a user's dashboard configuration, a shopping cart, IoT device readings — a blob of state belonging to one entity, read and written as a whole.
User-defined or rapidly-evolving schemas. A form builder where each customer defines their own fields; an early-stage product changing shape weekly. When you genuinely cannot fix the schema in advance, not having to is a real advantage.
The common thread: self-contained documents, read and written whole, whose shape varies or changes, with few relationships that must be enforced. When your data looks like that, MongoDB is not a compromise — it is the right tool.
Where documents lose
Equally real, and this is the half that "just use MongoDB" skipped.
Genuinely relational data. Money moving between accounts, an inventory decremented as orders
are placed, anything where entities relate to each other and those relationships must stay
correct. A bank, an ERP, an accounting system. Here you fight the model constantly:
multi-document transactions everywhere, $lookup everywhere, no foreign keys catching your bugs.
This is the big one, and it is where most misplaced MongoDB projects went wrong.
Complex ad-hoc reporting and analytics. "Revenue by region by product category by quarter, compared year on year." That is a few lines of SQL and a horror of a pipeline. Business intelligence tools speak SQL; the whole analytics ecosystem assumes it.
Strong consistency requirements by default. When every read must reflect the latest write and
no write may ever be lost, PostgreSQL gives you that out of the box; MongoDB gives it to you only
when you configure w: "majority", read from the primary, and use transactions — recreating, with
effort, what you would have had for free.
Data with many-to-many relationships at its core. Social graphs, permissions, tagging systems
where everything relates to everything. Referenced-id arrays and $lookup are a weak substitute
for a join, and if the relationships are the data, a graph database (module 12) or a relational
one fits better.
When you do not yet know your access patterns. Document design bakes your read patterns into the document shape. If you guess wrong, you restructure every document. The relational model, which does not commit to a read shape, is more forgiving of not-yet-known requirements — which is another reason it is the safer default.
The honest comparison
| Document (MongoDB) | Relational (PostgreSQL) | |
|---|---|---|
| Nested data read whole | Excellent | Needs joins |
| Varied / evolving shape | Excellent | Needs migrations |
| Relationships enforced | Weak (no foreign keys) | Excellent |
| Multi-entity transactions | Possible, discouraged, needs replica set | Routine and cheap |
| Ad-hoc queries & reporting | Harder, longer pipelines | Excellent |
| Consistency by default | Tunable, w:1 can lose writes |
Strong by default |
| Horizontal scaling (sharding) | Built for it | Harder (though improving) |
| Flexible per-record schema | Native | jsonb for the flexible parts |
Neither column is "better". They are different tools with different strengths, and the row that decides it for most applications is "relationships enforced" and "consistency by default" — which is why this course recommends starting relational.
The "just use MongoDB" mistake, dissected
Why did so many projects reach for MongoDB and regret it?
It demos beautifully. No schema to design, no migrations, JSON straight from the API into the database. The first week is a joy. The costs arrive in month six, when the data has grown relationships, reports are needed, and the drift has set in — long after the choice is expensive to reverse.
"Schemaless" was mis-sold as "no schema". The schema did not vanish; it moved into application code, undocumented and unenforced, and every reader now copes with every historical shape.
Scaling was oversold for the common case. MongoDB's horizontal scaling is real and genuinely better than PostgreSQL's, but most applications never reach the scale where it matters, and a single well-indexed PostgreSQL instance handles far more than people assume. Choosing MongoDB for scale you will not reach, and paying its costs for scale you do not need, is the classic error.
The reversal is expensive. By the time the mismatch is clear, migrating a large MongoDB dataset into a relational schema — inferring the shape, resolving the drift, rebuilding the relationships — is a major project. The cheap decision at week one became a costly one at month twelve.
How to actually decide
A short procedure, which the "choosing" module generalises to every database family:
- Write your main queries and access patterns first, before choosing anything.
- If they are mostly "fetch this whole thing and everything in it" with little cross-entity joining — lean document.
- If they involve relationships, transactions across entities, or ad-hoc reporting — lean relational.
- When unsure, choose PostgreSQL. It handles document-shaped data too —
jsonbwith GIN indexes gives you much of MongoDB's flexibility inside a relational database — so it is the lower-regret default. You can be relational where you need to be and document where you want to be, in one system. - You can have both. A real application often uses PostgreSQL for its core relational data and MongoDB for a genuinely document-shaped part — a CMS, a catalogue. Using more than one database on purpose is the "polyglot persistence" of the choosing module, and it is not a failure; it is maturity.
The one-sentence version: choose the document model when your data is genuinely documents, and do not choose it because designing a schema felt like work you wanted to skip.
Check your work
Five places documents genuinely win. Content management, varied product catalogues, event logs, per-user/real-time state, and user-defined or rapidly-evolving schemas.
Their common thread. Self-contained documents read and written whole, with varied shape and few enforced relationships.
Five places documents lose. Genuinely relational data, complex reporting, strong-consistency needs, core many-to-many relationships, and unknown access patterns.
The single biggest place they lose. Genuinely relational data — where you fight the model
with transactions and $lookup everywhere.
Why "just use MongoDB" was often wrong. It demos beautifully and the costs arrive months later; "schemaless" was mis-sold; scaling was oversold for apps that never reach that scale; and reversing the choice is expensive.
Where the schema actually goes in a "schemaless" database. Into application code, undocumented and unenforced.
Why PostgreSQL is the lower-regret default. It handles relational and (via jsonb)
document-shaped data in one system, and does not bake read patterns into the storage.
The deciding procedure. Write your access patterns first; lean document if they fetch whole things, relational if they join, transact, or report; when unsure, PostgreSQL; and you can use both.
What using two databases on purpose is called. Polyglot persistence — a sign of maturity, not failure.
Practice
- List five applications and classify each as more document-shaped or more relational, with a reason.
- Take one you called document-shaped and write its three main access patterns. Confirm they fetch whole things.
- Take one you called relational and try to model it in MongoDB. Count the places you would need
a transaction or a
$lookup. - Write "revenue by category by quarter" as SQL and as an aggregation pipeline. Compare.
- Design the flexible part of an app as
jsonbin PostgreSQL and as MongoDB documents. Compare what each gives up. - Find a real project that used MongoDB and research (or reason about) whether it fit. Write down the evidence.
- Sketch a two-database design for one application: what goes in PostgreSQL, what goes in MongoDB, and why.
- Argue the opposite case for one of your classifications, as strongly as you can. Decide whether it changes your answer.
Official documentation
- MongoDB — When to use MongoDB — The vendor's own framing; read it knowing it is a vendor.
- MongoDB — Data modeling anti-patterns — The shapes that signal a bad fit.
- PostgreSQL — JSON types — How PostgreSQL does document-shaped data, so you can weigh one system against two.
- PostgreSQL — jsonb indexing — GIN indexes on
jsonb, the flexibility argument for staying relational. - Martin Fowler — Polyglot persistence — The idea of using more than one database on purpose.
Next module: key-value stores and caching with Redis.
Stuck on this lesson?
Being stuck is part of it — but being stuck alone for three days is not. Our internship programme pairs this curriculum with code review and one-to-one help from working developers, and it is free.
About the internship