← Back to MongoDB
Lesson 1.3 · MongoDB Fundamentals

MongoDB Use Cases and Limitations

Where MongoDB shines - catalogues, content, user profiles, events, real-time apps - and where it struggles. Then hit its real limits on purpose: the 16 MB document limit (on insert and when a document grows), the nesting limit, and a typo that silently hid a product.

Beginner25 min

What you will be able to do

  • List the kinds of applications MongoDB fits well, and why
  • List the situations where a relational database may fit better
  • Explain the 16 MB document size limit and how it is reached
  • Know that very deep nesting is refused
  • Explain why a flexible schema can hide mistakes
  • Ask the right questions before choosing MongoDB for a project

The idea, in plain English

Every database is a tool, and every tool has jobs it is good at. MongoDB is good when your data is a collection of "things" that are read and written as a whole - a product, a user profile, a blog post with its comments - and when the shape of those things varies or changes over time.

It is weaker when the most important questions cross many kinds of data at once, with many-to-many links, or when most operations must change several records together. MongoDB can do joins and transactions, but if you need them in every request, a relational database may be simpler.

MongoDB also has hard limits you should know before you design. In this lesson we break them on purpose, on MongoDB 9.0.2, and read the exact errors.

Worked example: Five real-world apps checked against MongoDB’s strengths, then four experiments that break its limits on MongoDB 9.0.2.

workflowShould this app use MongoDB?step 1 / 2

Signals for MongoDB

Your data comes in "whole things" that are read and saved together, and their fields differ or change often.

product catalogue
good fit
user profiles
good fit
blog / CMS
good fit
events, logs, IoT
good fit

Three questions to ask about your data. Not rules - signals.

Words you will see in this lesson

A few words about fit and limits.

Small dictionary
Use caseA kind of job a tool is used for.
LimitationSomething a tool cannot do, or does badly.
BSONThe binary format MongoDB uses to store documents (Lesson 1.5).
MBMegabyte. MongoDB’s limit is 16 MiB = 16,777,216 bytes.
TransactionSeveral changes that succeed or fail together (Module 6).
Unbounded arrayA list inside a document that keeps growing without end.

An everyday example: a backpack vs a warehouse

A backpack is great: everything you need for the day is in one place, and you pick it all up at once. But a backpack has a size. If you keep adding things every day and never take anything out, one day the zip will not close.

A MongoDB document is that backpack: keep together what you use together - but do not put a whole warehouse in it. The warehouse with shelves and labels (separate collections, or a SQL database) is better for things you look up one by one, in many combinations.

Where MongoDB fits well

These are common, successful uses of MongoDB. Notice the pattern: each record is a "thing" with its own details, and the app mostly reads and writes one thing at a time.

Good use cases
Product cataloguesA shirt has sizes and colours, a laptop has CPU and RAM. Different fields, one collection.
Content and blogs (CMS)A post with its tags, author info and blocks of content, read in one go.
User profiles and settingsEach user has different preferences; new settings appear all the time.
Events, logs, IoT readingsLots of small documents written quickly; time series collections help.
Real-time and mobile appsJSON in, JSON out; change streams push updates to clients.
Fast-changing productsEarly-stage apps where the data model changes every week.

Where to think twice

MongoDB can handle all of these. But in each case you would be working against the document model, and a relational database may be simpler.

Weaker fits
Many-to-many in every queryStudents, courses, teachers, rooms - all joined all the time.
Heavy multi-record transactionsDouble-entry accounting where every action changes many rows together.
Ad-hoc reporting by analystsPeople writing new SQL joins every day; SQL tools are everywhere.
Strict, stable structureIf the shape never changes and must always be enforced, SQL gives that by default.

Limit 1 - a document can be at most 16 MB

One document can be at most 16 MiB: 16,777,216 bytes. We tried to save a document with a text just 100 bytes over 16 MiB. The server refused it and said exactly how big it was and what the maximum is.

A 15 MB document was fine - $bsonSize reported 15,728,689 bytes. Note that the size counts everything: field names, values and a little extra for the format. That is why 16,777,166 characters of text (50 bytes under 16 MiB) was also refused: the whole document came to 16,777,219 bytes.

For a much bigger value (17 MB) the error came even earlier, from mongosh itself, as a RangeError before anything was sent. Either way: big files do not belong inside a document. Store them in object storage (like S3) or GridFS, and keep only the link in the document.

limits.js - too big
use("limits13") for (const n of [16 * 1024 * 1024 + 100, 16 * 1024 * 1024 - 50]) { try { db.files.insertOne({ name: "n" + n, data: "x".repeat(n) }); print(n, "ok") } catch (e) { print(n, e.name + ": " + e.message) } } db.files.insertOne({ name: "large", data: "x".repeat(15 * 1024 * 1024) }) // 15 MB print("size in bytes:", db.files.aggregate([ { $project: { _id: 0, size: { $bsonSize: "$$ROOT" } } } // real size of the document ]).toArray()[0].size)
Output
16777316 MongoServerError: object to insert too large. size in bytes: 16777369, max size: 16777216 16777166 MongoServerError: object to insert too large. size in bytes: 16777219, max size: 16777216 size in bytes: 15728689

Limit 2 - documents that grow

Documents rarely start too big. They grow. We made a document with an empty array and pushed 5 MB into it, again and again - like comments on a popular post, or readings from a sensor. Three pushes worked. The fourth failed: "Resulting document after update is larger than 16777216".

This is the most common way to hit the limit in real apps: an array that grows without end (an "unbounded array"). The fix is a design choice - keep the growing items in their own collection, each with a link back. Lessons 2.15 and 2.17 show how.

A growing array
db.grow.insertOne({ _id: 1, chunks: [] }) const chunk = "y".repeat(5 * 1024 * 1024) // 5 MB for (let i = 1; i <= 4; i++) { try { db.grow.updateOne({ _id: 1 }, { $push: { chunks: chunk } }); print("push", i, "ok") } catch (e) { print("push", i, e.name + ": " + e.message) } }
Output
push 1 ok push 2 ok push 3 ok push 4 MongoServerError: Plan executor error during update :: caused by :: Resulting document after update is larger than 16777216

Limit 3 - nesting depth

Documents can hold documents, which can hold documents... but not forever. We wrapped a value in { inner: ... } again and again. MongoDB’s documentation promises 100 levels of nesting. Our 9.0.2 server accepted up to 179 wrappings and refused 200 with "BSONObj exceeds maximum nested object depth".

Plan for the documented 100, and in practice stay far below it. If your documents are more than a few levels deep, they are hard to query and update - that is a design problem long before it is a limit.

Output - deeper and deeper
depth 150 ok depth 200 MongoServerError: BSONObj exceeds maximum nested object depth in element with field name 'documents.0.inner.inner.inner.inner... largest wrapping count accepted: 179

Limit 4 - no rules, so typos hide

This one is not an error at all, and that is the danger. We saved two products. The second one had a typo: "pirce" instead of "price". MongoDB stored it without complaint.

Then we searched for products cheaper than 10. The Pen costs 2, but the result was empty: the Pen has no field called price, so it never matches. Nothing warned us. In a real shop, that product would silently disappear from every price filter.

The protection is up to you: schema validation in the database (Lesson 2.19), a typed model in your code (TypeScript and Mongoose, Module 5), and tests.

A typo
db.products.insertMany([{ name: "Lamp", price: 24.5 }, { name: "Pen", pirce: 2 }]) // "pirce"! printjson(db.products.find({ price: { $lt: 10 } }).toArray()) printjson(db.products.find({}, { _id: 0 }).toArray())
Output
[] [ { name: 'Lamp', price: 24.5 }, { name: 'Pen', pirce: 2 } ]

Watch out: MongoDB does not know which field names are "right". A misspelled field is a new field. Validate your data from the first day of a real project.

Questions to ask before you choose

Before choosing MongoDB for a project, answer these. If most answers point to "documents", MongoDB is a strong choice. If most point to "tables and joins", look at PostgreSQL too. Lesson 7.15 compares the two in depth.

Checklist
How is the data read?As whole objects (documents) or in many combinations (joins)?
Does the shape vary?Different fields per item, or changing every month?
What grows?Any list that grows without end must not live inside one document.
What must change together?If many records must change atomically all the time, plan transactions.
Who checks the data?Plan validation from day one.
How big will it get?Huge data or traffic: MongoDB’s sharding helps.

Limits at a glance

Document size

Hard limit.

16 MiB = 16,777,216 bytes
Measure a document

Real BSON size.

{ $bsonSize: "$$ROOT" }
Nesting depth

Documented limit.

100 levels
Big files

Outside the document.

object storage (S3) or GridFS + a link
Growing lists

Own collection.

comments: { postId, text, ... }
Typos

Add validation.

Lesson 2.19: $jsonSchema

Try it yourself

The code does not change. Swap the content string and the program does something else entirely.

Measure

“Use $bsonSize to measure one of your products. How many bytes is a small document?”

Limit

“How many 1 MB pushes fit into one document before the error? Predict first.”

Find the typo

“Find all products that have no price field: db.products.find({ price: { $exists: false } }).”

Classify

“For a hospital appointment system, a chat app and a bank ledger, write down: good fit or think twice? Why?”

What usually goes wrong

Storing files inside documents

Images and PDFs make documents huge. Store the file elsewhere and keep a link.

Lists that grow forever

Comments, log lines, readings - in one document they hit 16 MB. Use a separate collection.

No validation

The "pirce" typo was stored and the Pen vanished from searches. Validate from the start.

Forcing a relational model into MongoDB

If every query needs joins across many collections, the design (or the database choice) needs a second look.

Practice

Write these yourself before opening anything. Getting them wrong first is most of how this sticks.

1.

A blog stores each post as a document with all its comments in an array. Popular posts get 50,000 comments. Explain what will go wrong, and sketch a better design with two collections.

Show hint

The array grows without end - the document will approach 16 MB and every update rewrites a big document. Keep comments in their own collection with a postId field; keep maybe the latest 3 comments in the post.

Key points

  • MongoDB fits data read and written as whole objects, with shapes that vary or change.
  • Think twice for heavy many-to-many joins in every query, or many-record transactions everywhere.
  • A document can be at most 16 MiB (16,777,216 bytes) - including when it grows through updates.
  • Arrays that grow without end are the most common way to reach the limit.
  • Very deep nesting is refused; the documented limit is 100 levels.
  • No rules by default: typos create new fields silently. Validate your data.

Quick check before you move on

What is the maximum size of one document?
16 MiB = 16,777,216 bytes.
Why did the 4th push of 5 MB fail?
The document after the update would be larger than 16,777,216 bytes.
Why did the Pen not appear in the price search?
It was saved with "pirce", so it has no price field to match.
Name two good use cases for MongoDB.
For example: product catalogues, user profiles, content/CMS, events and logs.

Interview questions

What are MongoDB’s main limitations?

16 MB maximum document size, nesting depth limits, joins ($lookup) and multi-document transactions that are possible but costlier than single-document operations, no schema enforcement unless configured, and data duplication from embedding that must be kept consistent.

How do you handle data that would exceed 16 MB in one document?

Redesign: move growing arrays into their own collection (referencing or bucketing patterns), store large binary data in GridFS or object storage, and keep documents sized for how they are read.

Name workloads where MongoDB is a strong choice.

Catalogues, content management, user profiles and personalisation, IoT and event data (time series collections), mobile and real-time apps, and systems that need flexible schemas or horizontal scale-out.

Quiz

  1. 1.

    Where should you store a 50 MB video for a course app?

  2. 2.

    Why might a bank ledger fit SQL better?

  3. 3.

    What error did a document 100 bytes over 16 MiB give?

  4. 4.

    What does an unbounded array mean, and why is it a problem?

Comments

Sign in to leave a comment. Your name and photo come from Google; nothing else is shared.

Loading comments...