A publishing platform stores each post together with its author details and all comments inside one MongoDB document. The post page loads with one database lookup, which seemed ideal. A popular post reaches 100,000 comments, moderators edit comments independently, and some post updates become slow. Which fields would you embed, which would you reference, and what does that decision change about atomicity?
Assume the application mostly opens one post at a time, displays the first 20 comments initially, and needs to page through older comments. It also supports moderation searches across many posts.
Think first
Design a customer support case document. A case contains a title, current owner, status and an unlimited timeline of messages and attachments. Decide what belongs in the case document and how pagination, compliance exports and edits work.
Take a few minutes to form an approach, then compare it with the worked explanation.
Reveal the worked explanation
One object is a convenient boundary, until it isn't
Embedding a title, a small author snapshot and a short list of labels inside one post document can be sensible. Those fields are commonly read together and do not grow without bound.
Embedding every comment seems like the same decision, but the workload is different. Comments grow independently. They have separate authors, moderation states and update rates. The page rarely needs all 100,000 at once.
Bounded post metadata remains embedded while unbounded comments move to independently indexed documents.
MongoDB documents are limited to less than 16 MiB. That is a hard bound, not a performance target to approach intentionally. MongoDB's documentation describes embedding as useful when related fields are retrieved together and updated in a single atomic write, but it also states the document-size limit. MongoDB embedding
So I would start with the actual reads: post details, first page of comments, comments by one moderator, and replies to a specific comment. They do not all naturally share one document lifetime.
Move the unbounded part into its own collection
A practical model might have one posts document keyed by post ID and a comments collection keyed by comment ID, with postId, creation order, parent comment ID and moderation fields. The comment query uses an index matched to postId and the cursor sort order.
The first page can now fetch the post and a bounded comment page. That is more than one logical read operation, but it moves an amount of data proportional to the page size rather than the lifetime of the post.
A comment may be edited without continually contending with unrelated post metadata writes. Moderation can query by author, status or report identifiers through the indexes that correspond to those workflows.
If product wants five preview comments on the post card, I might keep a bounded preview snapshot in the post document as well. The important word is bounded. It is a deliberate duplicated read model, not an instruction to append every comment forever.
The tradeoff is now consistency between the comment collection and any preview or comment count. A count may lag or require reconciliation, depending on the product contract. For a moderation decision, the authoritative comment record should win over a stale preview. A small stale badge and an incorrectly visible prohibited comment are not equally acceptable inconsistencies.
The atomicity boundary changed
An important reason to embed related fields is atomic update within one document. Suppose a post title and its publication flag must change together. A single-document update can express that atomic modification. MongoDB embedding
After moving comments into a separate collection, updating the post and a comment is no longer one single-document operation. If a product feature genuinely needs those two changes to be all-or-nothing, the design needs a supported multi-document transaction or a workflow whose intermediate states are acceptable. Do not say “MongoDB cannot do transactions.” That is both inaccurate and unnecessary to the interview decision.
But transaction support is not a reason to embed an unbounded set. Data shape should reflect the dominant read and update patterns. Use cross-document coordination where a real business invariant requires it, not for every comment edit.
Think about deletion. If a moderator removes one comment, that comment record may be marked hidden while audit history remains, under the application's retention policy. If the post stores a cached preview, its invalidation should be scheduled or updated under an explicit freshness contract. Reading the old preview should never bypass the enforcement check for hidden content.
How do you migrate a large embedded array?
A production system may already have millions of existing posts with embedded comments. I would not flip the reader to a new collection before the data exists.
First, introduce readers that understand the old and new shapes under a schema version. Then backfill comments into a new collection with stable IDs and a record of which source ranges have been copied. During the backfill, live comments need one clear authoritative write route, plus a capture or dual-read strategy that prevents a comment from disappearing between source scan and cutover.
If the migration requires temporary dual writes, treat partial success as a real failure mode and have reconciliation. A versioned cutoff or generation pointer can tell readers which representation is authoritative. Verify samples, totals and ordering before retiring the old field. The exact mechanics depend on the available transaction and change-stream guarantees.
A migration that only compares aggregate comment counts can miss a duplicated comment canceling a missing one. Check identities and representative pagination boundaries too.
When embedding still wins
Suppose a post contains three poll options, each always read and updated with the post. Keeping those options embedded is natural. Separate collections would add reads and complicate an invariant without obvious benefit.
Now suppose comments are limited by product policy to ten, immutable after posting, and always displayed together. Embedding them may again be sensible. We should not promote a “never embed arrays” rule.
The useful interview answer comes from lifecycle, cardinality, access pattern and atomicity scope, not an arbitrary preference for normalization or denormalization.
The platform then adds full-text search across posts and comments. It creates another representation optimized for search. That representation can lag the primary documents, which creates a different type of correctness question.
Go deeper
Optional depth: updates, indexes and large document costs
Growing arrays also change the cost of indexing and document updates. The application may need index entries for embedded array values, and update patterns can affect contention and storage layout. These costs depend on the fields indexed and actual update operation, so do not assert that MongoDB rewrites every byte of the document for every update. Avoid relying on a 16 MiB maximum as your normal operating size. MongoDB explicitly recommends references when related records grow without bound, are queried independently, or change frequently. MongoDB data model references
Check your reasoning
Distinguish bounded post metadata from unbounded comments.
Connect independent update patterns to document boundaries.
Explain what single-document atomicity does and does not cover.
Choose stable pagination keys and a safe migration strategy.
Common mistake: Any one-to-many relationship must use an embedded document array.
Read the answer explanation
Use separate comment records for the unbounded collection and bounded previews where useful — Comments grow and update independently while only a bounded page is needed at once. The split changes the atomicity contract.
Apply it elsewhere
A multiplayer game's player document contains every match ever played. The leaderboard only needs the latest five. How would you reshape storage?
Compare your approach
Recognize bounded versus unbounded relationships. Select independent query paths. Explain single-document atomicity versus cross-document changes. Consider moderation or security checks on derived previews. Propose a safe evolution path.
One more constraint
A relationship is one-to-many. Is that fact alone enough to decide embed versus reference?
Quick revision
Embed fields that are bounded and normally read or updated with their parent. Reference records with independent lifecycles, unbounded growth, separate query patterns or frequent independent updates. Embedding provides a useful atomic document boundary, while referencing changes the consistency and transaction questions. The decision follows usage, not a rule that one document should represent an entire business object forever.