Almanac
Microsoft/power-biPower Platform

Consultant KB for Microsoft Power BI: semantic models, DAX and modelling, Power Query and dataflows, reports and visuals, the service and workspaces, capacity and performance, embedding and integration, governance and security, ALM and deployment, and licensing, plus cross-cutting decision guides. Scoped to Power BI, with Microsoft Fabric covered where it touches Power BI directly. Implementation notes, configuration decisions and the gotchas that bite on real projects. Populated by the daily author agent from the Power BI release plans, docs repo and product blog, plus the author's own consultant notes.

feature-filter-context-and-context-transition.mdv1 · history
CurrentApplies to BothUpdated last monthSource Microsoft Learn

What it does

Filter context is the set of filters in force when an expression is evaluated — everything the visual, slicers, page filters and relationships have applied. Row context is the "current row" that exists while a calculated column or an iterator function is walking a table. CALCULATE is the function that modifies filter context, and it's also the function that turns row context into filter context.

Key facts

  • CALCULATE evaluates an expression in a modified filter context. If a filter argument touches columns already in the filter context, it overwrites those filters. If it touches columns that aren't, it adds them.
  • Wrap a filter argument in KEEPFILTERS to add rather than replace.
  • Boolean filter arguments have rules: they can reference columns from a single table only, can't reference measures, and can't contain a nested CALCULATE. Since the September 2021 Desktop release they also can't use functions that scan or return a table unless those are passed to an aggregation function.
  • Filter modifier functions are REMOVEFILTERS, ALL / ALLEXCEPT / ALLNOBLANKROW, KEEPFILTERS, USERELATIONSHIP and CROSSFILTER. Where your tool supports REMOVEFILTERS, prefer it over ALL for clearing filters.
  • Multiple filter arguments combine with AND. Use && and || inside a single argument for finer control.
  • CALCULATE used with no filter arguments does one specific job: it transitions row context to filter context. That's context transition.
  • Referencing a measure inside an iterator triggers context transition implicitly, because a measure reference is wrapped in an invisible CALCULATE.
  • CALCULATETABLE is the same function for expressions that return a table.

When to use / skip

There's no skipping this one — it's the concept that everything else in DAX sits on top of. Until someone understands that a measure re-evaluates under whatever filters each cell implies, and that CALCULATE rewrites those filters rather than adding to them, every DAX problem looks like a mystery. The practical test is whether they can explain why CALCULATE([Sales], 'Date'[Year] = 2025) returns 2025 sales in a visual already sliced to 2024. If they can, the rest is detail.

Configuration decisions

  • Whether filter removal uses REMOVEFILTERS or the older ALL family, and that the team picks one and sticks to it.
  • Whether ranking and comparison measures use KEEPFILTERS to respect existing slicers, or deliberately override them — this is a business rules decision, not a technical one.
  • Where role-playing date relationships are handled: duplicate date tables with active relationships, or one table with inactive relationships and USERELATIONSHIP in the measures.
  • Whether context transition is used deliberately in iterators, or avoided by restructuring the calculation.

Gotchas

  • Context transition inside an iterator over a large table is the single most common cause of a slow measure. Every row triggers a fresh filter context. SUMX(Sales, [Some Measure]) over millions of rows will not end well.
  • People write CALCULATE([Sales], 'Date'[Year] = 2025) expecting an extra filter and get a replacement. The slicer selection vanishes and nobody can see why.
  • Context transition also applies existing row values as filters, which means a measure inside an iterator over a table with duplicate rows can produce results people find genuinely surprising.
  • EARLIER still appears in older code to reach outer row context. Variables do the same job more legibly, and there's rarely a reason to write EARLIER in a new model.
  • A calculated column has row context but no filter context from the report — it's evaluated at refresh. Writing a "current selection" calculation as a calculated column never works and the error message doesn't say so.

Consultant notes

  • Spend the training budget here rather than on function reference. A team that understands evaluation context can look up the rest; a team that doesn't will produce wrong numbers confidently.
  • When a measure gives an unexpected number, the first question is always "what's the filter context in that cell", not "what's wrong with the formula". Teach the debugging order.
  • Watch for iterators over fact tables in code review. It's the highest-yield thing to look for and it's usually visible at a glance.
  • Be careful describing this to clients as "advanced DAX". It isn't advanced, it's foundational, and framing it as advanced gives people permission to skip it.

Sticky note: if a number looks wrong in one cell and right in another, start with filter context before touching the formula.

Was this accurate?