Power Apps Delegation, Explained

Delegation is the #1 Power Apps pain point. Here's what delegates, what doesn't, and the patterns that keep your app correct as the data grows.

Last verified July 2026 against current Power Fx.

Almost every "my app works with test data but breaks in production" bug traces back to one thing: delegation. Understanding it is the single highest-leverage skill a Canvas App developer can have, because the failure is silent, you get wrong data, never an error message.

What delegation actually is

When you write Filter(Orders, Status = "Open"), Power Apps has two ways to run it:

  • Delegated, it sends the filter to the data source (SharePoint, Dataverse, SQL) and gets back only the matching rows. Fast, and correct no matter how many rows exist.
  • Non-delegated, it downloads the first 500 rows (raisable to 2000) and applies the filter locally in the app. If row 501 matched, you never see it.
The blue-underline "delegation warning" is not an error. The app runs fine, it just caps results at the data row limit and works on that subset. You get incomplete data, not an exception. That is why delegation bugs reach production.

What delegates, by data source

Delegation is per source. Dataverse and SQL are far more capable than SharePoint, most notably, they delegate aggregates that SharePoint cannot. This table covers the operations people hit most:

OperationSharePointDataverseSQL
=, <>, <, >, <=, >=
StartsWith()
Search() / EndsWith()
in (membership)partialpartial
And / Or / Not
Sum / Average / Min / Max
CountRows / CountIf
SortByColumns / Sort
Filter / LookUp / Search *
AddColumns / GroupBy / Distinct

* The function delegates, but only if what you pass it is also delegable, e.g. Filter(list, Search(...)) is non-delegable on SharePoint because Search() isn't. Table-shaping functions like AddColumns, GroupBy and Distinct run in-memory on every source.

The most common non-delegable trap is a "contains" search. On SharePoint, Search(), EndsWith() and the in operator all fall back to the row limit. StartsWith() delegates, so a prefix search stays correct at any scale:

Delegable prefix search (SharePoint-safe)Delegable
Filter(Items, StartsWith(Title, txtSearch.Text))
Non-delegable on SharePoint, silently caps at the row limitNot delegable
// "Contains" isn't a Power Fx function - these are the culprits:Filter(Items, Title in txtSearch.Text) // "in" - not delegable on SPFilter(Items, Search(Items, txtSearch.Text, "Title")) // Search() - not delegable on SP

If you genuinely need a mid-string match on SharePoint, your only correct options are to cache the list first (below) or move the column to a data source that delegates it.

Aggregates: fine on Dataverse/SQL, a trap on SharePoint

Sum, Average, Min, Max, CountRows and CountIf delegate on Dataverse and SQL but not on SharePoint. On a SharePoint list of 5,000 rows, Sum(Orders, Amount) quietly sums only the first 500 (or 2000):

Aggregate, Dataverse/SQL delegate, SharePoint doesn'tDepends
Sum(Orders, Amount) // delegates on Dataverse / SQL, not SharePointCountRows(Filter(Orders, Status = "Open")) // same story

On SharePoint, the reliable pattern is to cache the (delegably-filtered) rows locally, then aggregate the collection. Collections have no delegation limit because they already live in the app. This same client-computed-aggregate pattern is what makes unique keys racy, see the concurrency retry for the real-world failure and fix:

Cache with a delegable filter, then aggregate locally
ClearCollect(colOpen, Filter(Orders, Status = "Open")); // = delegatesSum(colOpen, Amount) // local, exact

Cache-and-work-local

The escape hatch for almost any delegation problem is to pull a delegably-filtered slice into a collection with ClearCollect, then do the non-delegable work (Search, GroupBy, Sum) on that collection. The key is that the filter feeding ClearCollect must itself be delegable, or you're just caching the first 500 rows.

Load once, then everything downstream is local
// Delegable pull (equality filter), then in-memory Search + GroupByClearCollect(colActive, Filter(Projects, Status = "Active"));// These are non-delegable, but colActive is already in memory - so it's fine:Filter(colActive, Search(colActive, txtFind.Text, "Name"));GroupBy(colActive, "Owner", "ByOwner")
Rule of thumb: delegate the fetch, localize the shaping. Get the smallest correct set of rows out of the source with a delegable filter, then reshape it however you like in a collection.

Raising the 500-row limit (and why it's not a fix)

Settings › General › Data row limit for non-delegable queries lets you raise the cap from 500 to a maximum of 2000. It buys headroom for small lists, but it is a band-aid: at 2,001 rows you're wrong again, and pulling 2000 rows into the client hurts load time and memory. Treat it as breathing room while you make the query delegable, not as a solution.

Quick checklist

  • See a blue underline? Assume the result is capped and wrong on large data. Fix it, don't ignore it.
  • Prefer = and StartsWith() over Search(), in, and EndsWith() on SharePoint.
  • Need Sum/Count on SharePoint? Cache a delegable slice first, then aggregate the collection.
  • Building complex shaping (GroupBy, AddColumns)? Do it on a collection, never on the raw source.
  • On Dataverse or SQL? You have far more room, but table-shaping functions still run in-memory.

FAQ

What is delegation in Power Apps?

Delegation is Power Apps pushing the work of a query (filtering, sorting, aggregating) down to the data source so the source returns only the matching rows. When a function can't be delegated, Power Apps instead pulls the first 500 rows (up to 2000) into the app and processes them locally, which silently produces wrong results on larger data sets.

Why is my delegation warning not stopping the app?

The blue-underline delegation warning is a design-time hint, not a runtime error. The app still runs. It just caps the data it pulls at the row limit and works on that subset. You get incomplete or wrong data, never an exception, which is exactly why delegation bugs slip into production.

Does the same formula delegate on SharePoint, Dataverse, and SQL?

No. Delegation is per data source. Dataverse and SQL delegate far more, including Sum, Average, Max, Min, and CountRows, while SharePoint cannot delegate aggregates and treats Search() and 'in' as non-delegable. Always check delegation against the source you are actually using.

How do I raise the delegation row limit?

In Power Apps Studio go to Settings › General › Data row limit for non-delegable queries and raise it (max 2000). This is a workaround, not a fix. It only masks the problem to 2000 rows. Keep your filters delegable, or cache the data with ClearCollect and work locally.