Embed data that belongs to the parent and is read with it. Reference data that is large, grows without limit, is shared, or is queried on its own.
Embed when the related data belongs to the parent and you read them together. Examples: an order's line items, or a user's addresses.
- One read returns everything.
- A write to a single document is atomic (it fully happens or does not happen at all), so you need no transaction.
- It works best for one-to-one and one-to-few relationships with a bounded size.
Reference (store the other document's _id) when the related data:
- is large,
- grows without limit,
- is shared by many parents, or
- is often queried on its own.
Examples: comments on a popular post, products shared by many orders, or users that belong to many groups. You then load the data with a second query or with $lookup.
A document can be at most 16 MB. Large documents are also slow to read and rewrite. So reference arrays that can grow without limit.
A common middle ground is to embed a small, often-read copy, such as the latest 10 comments, and reference the rest.
- Embed data that is read together, owned by the parent and bounded in size.
- Writes to a single document are atomic.
- Reference data that is unbounded, large, shared or queried on its own.
- A MongoDB document can be at most 16 MB.
- A hybrid approach embeds a small subset and references the rest.