The total that did not match the ERP
A finance manager rang the platform team on a Tuesday because two numbers disagreed. The open orders screen in a canvas app said one thing, the ERP report said another, and the gap ran to several thousand records. The app had been live for eight months and had passed user acceptance. Nobody had ever checked a number on it against anything else.
Nothing had failed. The screen asked a question the data source could not answer, so the platform pulled a limited set of rows back and counted those. When the table held a few thousand rows that set covered everything, so the count was right. The table kept growing, the limit did not move, and the count became a count of whatever came back.
That behaviour has a name, and understanding it separates makers who ship apps that hold up from makers who ship apps that are wrong in ways nobody spots. Power Apps will tell you about it if you read the editor carefully, and it will let you ignore it if you do not.
What the source evaluates and what the app evaluates
Delegation describes which side of the connection does the work. When you write a query the data source understands, the platform hands it over, the source does the selecting, and only the matching rows travel back, so a table holding a million rows can answer a narrow question in one round trip. When the query uses something the source cannot evaluate, the work has to happen in the app instead. The platform asks for a capped number of rows first, then applies your logic to that batch locally.
The consequence is the part that catches people. A non-delegable query does not raise an error. It hands back an answer computed over part of the table, and that answer looks completely ordinary on screen. A count comes back low, a search misses a customer who is in the system, a figure on a tile is short by thousands, and nothing says so. Someone acts on the number before anyone questions it.
Which operations get delegated depends on the data source and on the connector in front of it, and the answer differs between a Dataverse table, a SharePoint list and a SQL table. It also changes between releases as support is added. I am not going to print a function list here, because a list that is accurate today misleads someone next year. Read the current documentation for your connector, then confirm it against your own source at your own volumes.
Sample data hides the defect completely
The reason this keeps happening is testing. A maker builds against a table with two hundred rows, maybe two thousand. Every row fits inside the local limit, so every query gets evaluated over the whole table whether it was delegated or not. Every count is right, every search finds the record, and the app is signed off in good faith.
The defect arrives later, without a deployment. Nobody edits the app. The business keeps entering orders, the table crosses the line, and from that day the screen answers from a slice. There is no failed run to point at and no alert. The first signal is a person noticing that two systems disagree, months after the app started being wrong.
So test with production-scale data. Copy a realistic volume into a development environment, or generate enough rows to pass the local limit several times over, then repeat every check you did at two hundred rows. A maker who has only ever tested against sample data has not tested delegation at all, and the sign-off they collected does not mean what the room thought. Anyone who has chased a metric nobody can reproduce twice knows the argument that follows.
Filter at the source before anything else touches the data
Write the query so the source does the narrowing, and do it first, ahead of any other shaping. The condition that cuts the table down has to reach the data source in a form the source can evaluate. Anything applied after a step the source could not handle is applied to the slice the app already holds, so the result inherits the same problem.
Most screens that run into this were designed to show everything. A gallery bound to the whole orders table, a search box along the top, and a user expected to scroll. Design the screen so the person arrives with a narrowing choice already made, by site, by account, by status, by the current period. Ask for fewer columns while you are there. That will not change how many rows the local limit allows, and a wide table carrying long text fields makes every page of results slower to move and slower to render.
How you express a text match decides whether it can be delegated at all. Two ways of asking what the user sees as one question, one matching the start of a field and one matching text anywhere inside it, are not equally supported across sources. Begins-with comparisons are handled more widely than search-anywhere comparisons, so a free substring search box is a common way a screen drops into local evaluation. Confirm which form your source supports before you build the search.
Heavy counting belongs somewhere other than the screen
Aggregation is where canvas apps run out of road fastest. A sum or a count across a large table either goes to the source or gets computed over a slice, and the slice version produced the number the finance manager rang about. Where the source can compute the aggregate, let it. Where it cannot, move the work out of the app. A scheduled flow that calculates the figures overnight and writes them into a small summary table leaves the screen one row to read, and that read delegates without effort.
Be straight about the cases where the answer is different. A genuine aggregate over a large table, recalculated on demand, usually belongs in a reporting tool rather than on a canvas screen. If the requirement is a live dashboard across millions of rows, the conversation to have is Power BI or Fabric rather than a cleverer formula.
Habits that keep an app honest as it grows
The editor flags formulas it cannot delegate. Take the flags seriously, because they are the only automatic signal you get. They are also imperfect, they miss cases, and a clean editor proves nothing, so a flagged formula is a question you answer rather than a warning you clear away. Teams that refuse to ship a screen carrying an unexplained delegation warning catch most of this before users do.
Write down the volume the app was designed for. An app that was correct at ten thousand rows becomes wrong at fifty thousand with nobody touching a line of it, and whoever inherits it has no way of knowing what was assumed. Put the number in the app description with the date, and give the owner a quarterly reminder to check the real row counts against it. Dataverse capacity creeps up on teams the same quiet way.
Sometimes the honest answer is that the requirement has outgrown the tool. A screen that must search an entire large table on free text, aggregate it live and return exact figures is a request for an application with a server behind it. That conversation arrives more often than makers expect, usually once a low-code app has outgrown its maker. Before a canvas app goes live against a table that will grow, this is the list I work through.
- The row count in production today, and the count the app is expected to face in two years.
- Every screen tested against a copy of production volume rather than sample data.
- Every delegation warning either resolved or written down with the reason it is acceptable.
- Each gallery and lookup reaching the source with a narrowing condition the source can evaluate.
- Every total and count on a screen traced to a delegated query or a precomputed value.
- The designed-for volume recorded in the app description, with an owner and a review date.
Reconcile one number before the end of the week
Pick the busiest screen in your most-used app and find the largest table behind it. Get the row count from the source itself, never from the app. Then take one figure the screen displays, a count of open items is usually enough, and reconcile it by hand against the same question asked directly of the source.
If the two agree, record the row count and the date, and set a reminder to repeat the check when the table doubles. If they disagree, you have found it before a finance manager did, and what you owe the business is a design change rather than an apology.


