Running Total
A general DAX pattern for calculating running (cumulative) totals over any sorted column, not just dates.
Running Total
A running total adds each row to the sum of everything before it.
Month | Sales | Running Total
----------|---------|---------------
January | 50,000 | 50,000
February | 60,000 | 110,000
March | 45,000 | 155,000Time-based running totals (like Year-to-Date) have dedicated DAX functions — see Time Intelligence. This page covers the general pattern, which works over any sortable column, not just dates.
The General Pattern
Running Total =
CALCULATE(
[Total Sales],
FILTER(
ALL(DimDate[Date]),
DimDate[Date] <= MAX(DimDate[Date])
)
)FILTER(
ALL(DimDate[Date]), all dates, filters removed
DimDate[Date] <= MAX(DimDate[Date]) keep only dates up to the current row
)MAX(DimDate[Date]) picks up the current row's date from context. FILTER() keeps every date less than or equal to it. ALL() makes sure the comparison set isn't limited to whatever's already been filtered.
Anatomy of a running total
Evaluating the Feb '26 row of the visual
1ALL() reopens the dates
Visual context: Feb '26 only → ALL(): all 5 months
2MAX() reads the row
Evaluated in the visual's context, not ALL()'s: Feb '26
3<= keeps the past
4 of 5 dates survive: 40 + 35 + 50 + 60
✓$185K
Running Total — every visual row
| Row | Nov25 | Dec25 | Jan26 | Feb26 | Mar26 | Total |
|---|---|---|---|---|---|---|
| Nov '25 | 40 | · | · | · | · | $40K |
| Dec '25 | 40 | 35 | · | · | · | $75K |
| Jan '26 | 40 | 35 | 50 | · | · | $125K |
| Feb '26 | 40 | 35 | 50 | 60 | · | $185K |
| Mar '26 | 40 | 35 | 50 | 60 | 45 | $230K |
4Within Year — adds Year = MAX(Year)
| Row | Nov25 | Dec25 | Jan26 | Feb26 | Mar26 | Total |
|---|---|---|---|---|---|---|
| Nov '25 | 40 | · | · | · | · | $40K |
| Dec '25 | 40 | 35 | · | · | · | $75K |
| Jan '26 | · | · | 50 | · | · | $50K |
| Feb '26 | · | · | 50 | 60 | · | $110K |
| Mar '26 | · | · | 50 | 60 | 45 | $155K |
ALL(DimDate[Date]) — the visual row has already filtered the dates down to one month. ALL() hands FILTER() every date instead. Without it, FILTER() only sees Feb '26, and the "running total" is just that month's $60K.
MAX(DimDate[Date]) — the outlined cell in each row. It runs inside FILTER()'s row loop, but row context doesn't filter anything, and ALL() only shaped FILTER()'s input table, not the filter context. So MAX() still sees the visual's filter and returns the current row's date, not the last date in the table.
<= — tested against every date ALL() returned, so each row keeps one more month than the row above it. The grey cells were scanned and rejected: 5 rows × 5 dates = 25 comparisons here, which is why this pattern slows down on long date columns.
&& DimDate[Year] = MAX(DimDate[Year]) — a second condition that rejects earlier years too. The staircase restarts in January, so Feb '26 keeps only Jan + Feb = $110K instead of $185K.
Result — CALCULATE() replaces the visual's date filter with the surviving dates and evaluates [Total Sales] over them.
Running Total Over Any Sorted Value
The same pattern works over a rank or sequence number, not just a date.
Running Total by Rank =
CALCULATE(
[Total Sales],
FILTER(
ALL(DimProduct[SalesRank]),
DimProduct[SalesRank] <= MAX(DimProduct[SalesRank])
)
)Useful for cumulative charts like "what percentage of total sales come from the top N products" (a Pareto / 80-20 analysis).
Running Total Within a Group
Restarting the running total for each group (like each year) combines the pattern with a group-preserving filter.
Running Total Within Year =
CALCULATE(
[Total Sales],
FILTER(
ALL(DimDate[Date]),
DimDate[Date] <= MAX(DimDate[Date]) &&
DimDate[Year] = MAX(DimDate[Year])
)
)Year | Month | Sales | Running Total
-----|-----------|---------|---------------
2025 | November | 40,000 | 40,000
2025 | December | 35,000 | 75,000
2026 | January | 50,000 | 50,000
2026 | February | 60,000 | 110,000The running total resets at the start of each year, instead of accumulating across the entire date range.
Running Total Using Time Intelligence Functions
For calendar-based running totals specifically, TOTALYTD(), TOTALQTD(), and TOTALMTD() are simpler and more efficient than the generic FILTER() pattern.
Sales YTD =
TOTALYTD(
[Total Sales],
DimDate[Date]
)Use the generic FILTER()-based pattern when the running total isn't calendar-based — ranks, sequence numbers, or any other sortable column where the built-in time intelligence functions don't apply.
The Time Intelligence Generator writes both versions for your own measure: year-to-date with the time intelligence functions, and an all-time running total with the FILTER() pattern.
Performance Considerations
The FILTER(ALL(...), ...) pattern re-evaluates across the full unfiltered column for every row, which can be slow on very large date or rank columns.
Rows evaluated per cell = size of the unfiltered column
For calendar dates specifically, TOTALYTD() and related functions are generally faster, since they're optimized internally rather than relying on a generic row-by-row filter scan.
Best Practices
- Use dedicated time intelligence functions (
TOTALYTD(), etc.) for calendar-based running totals. - Reserve the
FILTER(ALL(...), ...)pattern for running totals over non-date columns. - Test running total measures against a large, realistic dataset — this pattern's performance degrades with column size.
- Add a group condition (like Year) when the running total should reset periodically instead of accumulating indefinitely.
Common Mistakes
Using FILTER(ALL()) for Simple Date Running Totals
When the running total is just Year-to-Date or similar, TOTALYTD() does the same job more efficiently and more clearly than the generic pattern.
Forgetting to Reset Within Groups
A running total that should restart each year, but doesn't include the year condition in the FILTER(), will keep accumulating across year boundaries instead of resetting.
Sorting Assumptions
The pattern depends on comparing values with <=. If the column being compared isn't naturally ordered the way the business expects (like a text field instead of a number or date), the "running total" won't make sense.
Running Total Checklist
Before publishing a running total measure:
- Calendar-based running totals use
TOTALYTD()/TOTALQTD()/TOTALMTD()where possible. - Non-date running totals correctly use
FILTER(ALL(...), ...)over a genuinely sortable column. - Group resets (like per-year) are included if the business logic requires them.
- Performance has been tested against production-scale data.
Next Steps
Continue exploring DAX patterns:
Percent Of Total
Common DAX patterns for calculating percent of total, percent of parent, and percent of a specific category.
Earned Value Management (EVM) Metrics
Ready-made DAX patterns for Planned Value, Earned Value, Actual Cost, CPI, SPI, and the standard EAC/VAC/TCPI forecasting measures used in program and systems engineering status reporting.