pbPassingBI
/
DAX beginner 9 min

Measures vs. calculated columns

When each evaluates, what each costs, and how to choose.

What you'll be able to do
  • Choose between a measure and a calculated column
  • Explain row context and when it exists
  • Avoid the memory cost of unnecessary columns

Calculated columns

A calculated column is computed at refresh, row by row, and stored in the model. It has row context — it knows which row it's on, so [Price] * [Quantity] works directly.

Because it's stored, it consumes memory and increases model size. Use one when you need a value to slice, filter, group, or put on an axis — something that behaves like a real column.

Measures

A measure is computed at query time, in the filter context created by the visual. It has no row context, so it must aggregate: SUM(Sales[Amount]), not Sales[Amount].

Measures store nothing. They cost CPU when a visual renders, not memory. Use one for anything you'd put in the Values well of a visual.

The default choice

Prefer measures. They're flexible, respond to filter context, and don't inflate the model.

Reach for a calculated column only when you genuinely need a static per-row attribute to slice by — a bucket label, a flag, a concatenated key. And if you need one, ask whether it belongs in Power Query instead, where it's computed once at the source rather than by the DAX engine.

Iterators bridge the gap

Sometimes you need per-row arithmetic inside a measure. That's what the X functions are for:

Revenue = SUMX(Sales, Sales[Quantity] * Sales[Price])

SUMX iterates the table, creates row context for each row, evaluates the expression, then sums the results. This gives you row-level logic without storing a column — usually the better answer than a calculated column plus SUM.

Key points
  • Columns compute at refresh and cost memory; measures compute at query time and cost CPU
  • Default to measures; add columns only when you must slice by the value
  • SUMX and friends give row context inside a measure
Check yourself