Running Totals in Power Apps Galleries: Two Approaches and Optimization Tips
Learn to calculate running totals in a Power Apps gallery using filtered sums and collection-based improvements, with an example from project hours tracking.
A running total—the cumulative sum of all previous rows as you move through a list—is a common reporting need. Power Apps doesn’t offer a native running‑total function, but you can build one using Filter and Sum inside a gallery. In this article we’ll explore two practical patterns with a real‑world dataset and examine a collection‑based technique that can significantly improve performance when your data fits within the row limit.
Sample Data: ProjectHours List
Imagine you manage a construction company and you log weekly hours by project. A SharePoint list called ProjectHours holds the records.
| ID | WeekStart | ProjectName | HoursLogged |
|---|---|---|---|
| 1 | 2026-01-06 | Office Building | 40 |
| 2 | 2026-01-06 | Bridge | 35 |
| 3 | 2026-01-13 | Office Building | 42 |
| 4 | 2026-01-13 | Bridge | 38 |
| 5 | 2026-01-20 | Office Building | 44 |
| 6 | 2026-01-20 | Bridge | 40 |
We’ll display each row in a Power Apps gallery and show a running total of HoursLogged—first across all rows, and later grouped per project.
Basic Running Total: Cumulative Hours
Add a gallery bound to the ProjectHours data source, and include a label for the running total. Set the label’s Text property to the following expression.
Sum(
Filter('ProjectHours',
WeekStart <= ThisItem.WeekStart
),
HoursLogged
)For every row, the Filter retrieves all records whose WeekStart is on or before the current row’s week, then Sum adds up HoursLogged. The gallery now shows a cumulative total that increases as you scroll down.
The <= operator on a date field is not delegable in most standard connectors. This means Filter can only return the first 2 000 rows. The direct gallery method works well for small lists but will produce incorrect totals if the list grows larger than the delegation limit.
Grouped Running Total: Cumulative Hours by Project
Often you need a running total that restarts for each group—for example, cumulative hours per project. Modify the Filter to include a condition on ProjectName.
Sum(
Filter('ProjectHours',
ProjectName = ThisItem.ProjectName,
WeekStart <= ThisItem.WeekStart
),
HoursLogged
)Now the running total is calculated independently for each project. Rows belonging to different projects do not affect each other’s cumulative sum.
Performance Optimization with a Collection
The approaches above cause one data source call per gallery row (plus the initial query). If your list contains 500 rows, that’s 501 calls. You can reduce this to just two calls by pulling the data into a local collection and computing the running totals there.
This technique is only recommended when the total number of rows is 2 000 or less (the default non‑delegable row limit).
First, download the data and add a column to hold the running total.
ClearCollect(colProjectHours,
AddColumns('ProjectHours', "RunningTotal", 0)
)Then replace the zero values with the actual cumulative sums.
UpdateIf(
colProjectHours As Row,
true,
{
RunningTotal: Sum(
Filter(colProjectHours,
ProjectName = Row.ProjectName,
WeekStart <= Row.WeekStart
),
HoursLogged
)
}
)Change the gallery’s Items property to colProjectHours and set the running‑total label’s Text to ThisItem.RunningTotal.
Because the Filter now operates on the in‑memory collection, no delegation limits apply. The entire calculation runs on the local device, eliminating repeated server round‑trips.
The UpdateIf statement still loops through the collection row by row, but that happens entirely on the client. For two thousand rows the operation is nearly instantaneous.
Common Mistakes and Delegation Considerations
-
Grouping without a reset condition If you forget to add the grouping field (e.g.,
ProjectName = ThisItem.ProjectName), the running total will accumulate across all rows instead of restarting per group. -
Using
ThisItemoutside the gallery’s context TheFilterexpression must be placed on a label inside the gallery; otherwiseThisItemis not available. -
Ignoring delegation warnings When using the direct filter approach, Power Apps will show a yellow delegation warning for the
<=condition. This is expected but limits the data size. If your list exceeds 2 000 rows, consider using the collection method or pre‑aggregating the totals in the data source. -
Collection size The collection method works only if the entire data source fits within the non‑delegable row limit (2 000 rows). For larger datasets, explore server‑side computed running totals (e.g., in SQL views or SharePoint calculated columns).
Final Recommendation
- For small lists and simple demos, the direct
Filter/Sumexpression inside the gallery is quick to implement. - For any real app where you need smooth scrolling and predictable performance, use the collection‑based approach—as long as the total rows remain under the delegation threshold.
- If your data is too large for either method, consider moving the running‑total calculation upstream (into Power Automate, a SQL view, or a data source that handles it natively).
References
- Matthew Devaney, Power Apps Running Totals In A Gallery (original technique – see
originalReferencein the frontmatter). - Microsoft Learn: Filter function in Power Apps (search for “Filter” in the official documentation).
- Microsoft Learn: Create and use collections in Power Apps (search for “ClearCollect” and “UpdateIf”).
Learn how small coding practices—like using descriptive names, flattening conditions, and simplifying logic—can make your apps easier to update and less error-prone.
Move past the gallery and discover the hidden patterns for validation, navigation, and smart submission handling in your data entry forms.
PowerShell unlocks admin capabilities that the Power Platform admin center simply doesn’t offer—from recovering deleted apps to blocking trial licenses. Here’s how to wield them safely.