Skip to content

Data Modeling

Denormalization and Duplication

Copying a name onto an order so reads stay fast — and who is responsible for keeping it true.

AdvancedAbout 6 minutes

Duplication is a tool. You copy a field so the common read does not $lookup. The cost is who updates the copies, or whether they are allowed to go stale. That choice is the design, not an accident.

Snapshot — meant to freeze

  • items.unitPrice on the order
  • items.name at checkout
  • A price change must not rewrite history
  • No sync job

Live copy — meant to match source

  • user.city duplicated onto every order
  • product.rating duplicated onto a card cache
  • Rahul moves → every order is wrong until you fan out
  • Needs a rule: sync, or accept stale
{
  userId: ObjectId("64a1b2c3d4e5f6a7b8c90001"),
  items: [
    { productId: ObjectId("…"), name: "Mechanical Keyboard", quantity: 1, unitPrice: 4500 }
  ],
  amount: 4500
}

// Catalogue can go to 4999 tomorrow. This order stays 4500.
Correct duplication: the receipt, not the catalogue

Copy when the field is read far more than it changes, and either it is a snapshot or you have an update path (same service updates product title and $updateMany on a cache collection — rare, and easy to get wrong). Do not copy a field you will $lookup anyway. Do not copy a field that changes hourly unless you have a cache with TTL.

Interview question

When is denormalization in MongoDB a good idea?

Think about it first.