Data Modeling
Model to the access pattern
MongoDB schemas are designed around how the application reads and writes, not around normalization. The guiding principle: data that is accessed together should be stored together. Embed when the child data is bounded, read with the parent, and updated atomically with it. Reference when the data is unbounded, shared across many parents, or large enough to approach the 16 MB document limit.
Recognizable patterns
One-to-few: embed an array of subdocuments. One-to-many and many-to-many: store an array of _id references on one side, or use a linking collection. The subset pattern keeps only the most recent N items embedded and archives the rest. The extended reference pattern copies a few frequently read fields from the referenced document to avoid $lookup. The computed pattern precalculates aggregates. The bucket pattern groups time-series-like data into fixed-size documents.
Constraints
A BSON document is capped at 16 MB, so unbounded arrays ($push on a growing list) are an anti-pattern - they eventually fail and degrade write performance as documents are rewritten. Schema validation ($jsonSchema) enforces shape at the collection level, but it is not a substitute for modeling.
Atomicity
Single-document writes are atomic. If a business operation must be atomic across several documents, either remodel so the related data lives in one document, or use a multi-document transaction.
Worked rule of thumb
Ask: "Can this array grow without limit?" If yes, reference instead of embed. If no, and the parent is always read with the children, embed.