Optimizing Canvas Apps: Fix Slow Dataverse Gallery Loads with Delegation

A troubleshooting guide for anyone watching a Power Apps gallery crawl through five thousand Dataverse rows: what delegation actually does, which formulas break it, what to rewrite, and how to prove the fix worked.

A Power Apps canvas gallery that crawls over five thousand Dataverse rows is almost always a delegation problem. Delegation means the filtering, sorting and counting happen in Dataverse and only the matching rows travel to the app. When a formula cannot be delegated, Power Apps pulls the first five hundred rows, evaluates locally, and gives you an answer that is both slow and wrong. The fix is to rewrite Filter, Search and Sort with delegable functions, stop pulling columns and related records you do not display, reduce the working set the gallery is asked to show, and prove it with Monitor.

Two notes before the detail. First, which functions delegate is decided per connector and Microsoft revises the list, so treat the function names below as the shape of the problem and confirm the current behaviour in the Power Fx delegation documentation and, more usefully, in Power Apps Studio itself. Studio marks every non delegable formula with a warning while you type, and that warning is the authoritative answer for your app on the day you are looking at it. Second, we do not publish load time benchmarks. How long a gallery takes depends on table width, how many related records each row touches, what else runs in OnStart, and the device the app is on, so any number quoted without seeing the app is decoration. What we can give you is the arithmetic on the row limits and the order in which to change things.

The answer in three lines

Delegation decides where the work happens

A delegable formula is sent to Dataverse, which filters five thousand rows down to the twenty that match and returns those. A non delegable formula is evaluated inside the app, so Power Apps first has to download rows to evaluate against, and it will only ever download up to the data row limit. Every performance difference you are seeing follows from which of those two things your Items property is doing.

A slow gallery is usually also a wrong gallery

This is the part the speed question hides. If your filter is not delegated, it runs against the first five hundred rows only. Row four thousand nine hundred can match your criteria perfectly and never appear. Users report it as missing data months later, long after the app was signed off against a test table with two hundred rows in it. Fixing delegation is a correctness fix that happens to also make the app fast.

Raising the data row limit to two thousand is not the fix

It is the first thing everybody tries and it makes things worse in both directions. The app now downloads four times as much data on every screen, so it gets slower, and the correctness bug is still there, just hidden until the table passes two thousand rows. Set the limit back to five hundred while you diagnose. If lowering it changes your results, you have found a non delegable formula.

Why the gallery is slow, and why it is rarely only delegation

Delegation is usually involved, and on most apps we look at it is not the only thing costing time. Fixing the Filter formula and nothing else typically removes part of the wait and leaves the user still describing the app as slow. These are the causes worth checking, in the order they tend to matter.

A non delegable predicate in the Items property

The direct cause and the one Studio will tell you about. Something in the Filter or Search formula cannot be translated into a Dataverse query, so the whole formula stops being delegated. It is rarely the function you suspect. A single text manipulation, a comparison against a column of a related record, or an expression on the left hand side of the comparison is enough to break delegation for the entire statement.

The whole table collected at app start

ClearCollect over a five thousand row table in OnStart is a pattern people adopt precisely because delegation was confusing, and it is the most expensive thing in most slow apps. The user waits through the entire download before the first screen appears, the collection is capped at the data row limit anyway, and it goes stale the moment somebody else edits a record. It replaces a delegation problem with a delegation problem plus a startup problem plus a staleness problem.

Lookups running once per visible row

A LookUp call inside a gallery template is evaluated for every row the gallery renders, so scrolling issues a request per row per lookup. Two of them in the same template doubles it. This is the classic reason a gallery feels fine on the first screen and then stutters continuously as the user scrolls, and it is invisible in the formula bar because each individual call is cheap.

Retrieving columns nobody displays

A wide table with a hundred columns costs a hundred columns of payload per row unless the app is told otherwise. Explicit column selection is the setting that limits the retrieve to the columns the app actually references, and on wide tables the difference in payload size is large. It is also easy to defeat by accident, by passing a whole record into a component or a variable in a way that makes the app assume every column is needed.

Sorting on something the server cannot sort on

Sort and SortByColumns delegate, but only over a column the data source can order by. Sort over a calculated expression, a concatenation of two columns, or a value from a related record is evaluated locally, which quietly turns a delegated query into a non delegated one even though the Filter around it looked correct.

A search box that queries on every keystroke

A text input wired straight into the gallery Items fires a query for every character typed. Seven characters is seven round trips, six of which are already obsolete before they return. The user experiences this as the whole app freezing while they type, and it is entirely separate from whether the query itself is delegable.

Showing five thousand rows in the first place

The honest one. Nobody scrolls five thousand rows. A gallery is a work queue, and a work queue that opens on everything is a design decision rather than a technical constraint. The apps that feel instant are the ones that open on the twenty rows assigned to the person looking at the screen, with search and filters to reach the rest. Perfect delegation over an unbounded set is still a worse experience than a bounded set.

Images and files rendered in the row template

Image columns, file columns and attachment thumbnails in a gallery row are a separate download per row, and they are not covered by anything in the delegation documentation. On a list view they are usually decoration. Moving them to the detail screen removes a class of network traffic that no formula rewrite would have touched.

The data row limit, and why raising it makes things worse

This section exists because raising the limit to two thousand is the most common response to the symptom and it is the wrong one in both directions. It is worth understanding exactly what the setting does, because used correctly it is the fastest diagnostic you have.

What the data row limit is

An app level setting, found under the general settings of the app, that caps how many rows Power Apps will retrieve for a non delegable operation. It defaults to five hundred and the maximum is two thousand. It has no effect at all on delegable queries, which is the detail that makes it such a good diagnostic: if changing this number changes what your gallery shows, something in your formula is not being delegated.

What happens when a formula is not delegated

Power Apps retrieves up to the limit, in the source order the connector returns, and applies your filter to that subset in the client. There is no error and no warning at runtime. The gallery shows a plausible, incomplete answer. On a five thousand row table with the default limit, you are filtering ten percent of your data and presenting the result as if it were all of it.

Why the maximum of two thousand is not a solution

Two thousand of five thousand is still forty percent. The app pays four times the download cost on every screen that touches the table, on whatever connection the user has, and the correctness problem returns the day the table grows. It buys you a slower app and a delayed bug. The only case where raising it is legitimate is a table you can guarantee will stay small, and guarantees like that tend not to survive a second department joining.

How a delegated gallery actually loads

When the query is delegable, the gallery does not download five thousand rows at all. It requests a page of rows, renders them, and requests the next page as the user scrolls. The row limit is irrelevant and the table can be far larger than it without anything changing. This is why a correctly delegated gallery over a large table can feel faster than a badly written one over a small table.

Where the warning appears

Power Apps Studio underlines the non delegable part of the formula and shows a delegation warning on the control. The warning names the specific function or operator that could not be delegated, which is the fastest route to the cause. Treat every one of them as a defect to be closed rather than a suggestion, and do not ship an app with open delegation warnings on any table that can grow.

The tool that proves it

Monitor, opened from Studio or against a published app, records every network call the app makes with its duration and its payload. It is the only honest measurement available, and it settles arguments quickly: you can see whether the filter went to the server, how many rows came back, how many separate requests one scroll produced, and which of them was actually slow. Change nothing until you have looked at it.

What delegates to Dataverse and what does not

Organised by what you are trying to do rather than alphabetically, and with the workaround in every row, because the workaround is the part a function reference does not give you. Confirm anything critical against the current Microsoft delegation documentation and against the warning Studio shows in your own app.

What you are doingDelegated to Dataverse?What to do about it
Filter and LookUp with simple comparisonsDelegable. Equals, not equals, greater than, less than, and the And, Or and Not operators combining them all translate into a Dataverse query.This is the target shape. Keep the column on the left of the comparison and a plain value or a variable on the right, and the whole statement stays on the server.
StartsWithDelegable against Dataverse text columns, which makes it the workhorse of any search box that has to scale.Use it as the default search predicate. Most users searching a customer list are typing the beginning of a name, so the behaviour is usually what they expected anyway.
The in operator used as a substring testNot delegable. This is the single most common cause of a slow gallery, because it reads naturally and it is what most people write first.Replace it with StartsWith where the semantics allow. Where a genuine contains search is a hard requirement, use the Search function or move the query server side rather than accepting a client side scan.
Text functions such as Len, Left, Mid, Upper and Lower inside a filterNot delegable. Wrapping a column in any of them makes the comparison a client side expression and breaks delegation for the entire formula.Do the transformation before the filter runs, into a variable, or store the derived value in its own Dataverse column maintained on the server so the filter can compare against a plain column.
Filtering on a column of a related recordNot delegable in the general case. Walking from the row to its parent inside a Filter predicate is evaluated in the client.Filter on a lookup column directly where you can, since comparing the lookup itself is a comparison against a column on the row. Otherwise denormalize the one value you filter on onto the child table and keep it current with a plugin or a flow.
Sort and SortByColumnsDelegable over a sortable column, not delegable over an expression. Sorting by two columns concatenated, or by anything computed, is done in the client.Sort by a real column. If the ordering the business wants is genuinely composite, materialize it as a column on the table and sort by that.
CountRows, Sum, Average, Min and MaxDelegable against Dataverse within documented limits, so a count on a large table does not have to download the table.Where an aggregate is not delegable, or where the number is expensive and shown on a dashboard, precompute it: a rollup column, a plugin maintained field, or a Power Automate flow writing a summary row.
AddColumns, GroupBy, Distinct and UngroupNot delegable. They are table shaping operations that run on whatever the app already has in memory, which is at most the data row limit.Reduce the set with a delegable Filter first, then shape the small result. If the grouping is the point of the screen, do the grouping in Dataverse or in Power BI rather than in Power Fx.
ForAll over a data sourceNot delegable as a query mechanism. Iterating a table to build a result set downloads the table and is slow at any meaningful volume.Express the requirement as a filter. Where it genuinely cannot be, move the loop server side into a flow or a custom API and call it once from the app.
Collect and ClearCollect over a whole tableCapped by the data row limit, so a collection built from a five thousand row table silently contains five hundred rows.Collect only small, stable reference data. Point galleries at the data source directly so paging and delegation can do their work, and accept that a cached copy of a large table is a bug rather than an optimisation.

The fix, step by step

Steps 1 to 3 find the cause. Steps 4 to 8 fix the query and the payload. Steps 9 and 10 fix the design, which is usually where the largest improvement is. Steps 11 and 12 handle what is left and prove it. The order matters, because rewriting formulas before you have a Monitor trace is optimising a number you have not measured.

  1. Measure with Monitor before you change any formula

    Open Monitor from Power Apps Studio, load the screen, and scroll the gallery. You will see every network call with its duration and the number of rows it returned. Read it before touching anything. It tells you whether the wait is one slow query, five hundred rows of payload you did not need, or a hundred small lookup calls fired by the row template, and those three findings lead to three different fixes.

  2. Set the data row limit back to five hundred and see what changes

    If somebody raised it to two thousand to make a symptom go away, put it back to five hundred in the app settings while you diagnose. If the gallery contents change when you do, you have proved that a formula is not being delegated and is filtering a subset. That is a faster diagnosis than reading the formula, and it also stops the raised limit from masking the next problem you introduce.

  3. Close every delegation warning in the app, not just the one on the gallery

    Studio marks non delegable formulas as you type and names the operator responsible. Work through all of them, including the ones on screens nobody has complained about yet, and record which function broke each formula. A single non delegable element makes the entire statement non delegable, so the fix is usually one operator rather than a rewrite.

  4. Rewrite the filter so the column is on the left and a value is on the right

    Delegation works on comparisons between a column and a value. Move every calculation, text manipulation and function call out of the predicate and into a variable computed before the Filter runs, then compare against that variable. This single mechanical change fixes a large share of real delegation warnings without altering what the formula means.

  5. Replace the in operator with StartsWith in search predicates

    A contains style search using the in operator is not delegated to Dataverse and is the most common cause of a slow gallery. StartsWith is delegated and matches what most users are doing when they type into a search box. Where a true contains search is genuinely required by the business, treat it as a server side problem rather than as a formula to be tuned.

  6. Make the search box wait for the user to stop typing

    Turn on delayed output on the text input so the gallery queries once when typing pauses instead of once per keystroke, and do not query at all until two or three characters have been entered. On a large table this removes most of the requests the app was making, and it costs nothing but a property change.

  7. Remove LookUp calls from the gallery row template

    A lookup inside the template runs per rendered row. Resolve the value another way: use the lookup column already on the row where the display name is enough, denormalize the field you need onto the table, or fetch the related set once into a small collection before the gallery renders and reference that. The measurable effect is on scrolling, which is where users judge an app as slow.

  8. Turn on explicit column selection and stop retrieving unused columns

    Confirm explicit column selection is enabled for the app so Dataverse returns only the columns the app references. Then check you are not defeating it by passing whole records into components or variables in a way that forces a full retrieve. On a wide table this reduces payload per row substantially and it requires no change to the query itself.

  9. Bound the set the gallery opens on

    Default the gallery to the rows that person needs right now, which is usually their own records, or open items, or this week, and let search and filters reach the rest. Five thousand rows in a scrolling list is not a requirement anybody asked for, it is what happens when nobody decided. This is the change that makes an app feel instant rather than merely correct.

  10. Stop collecting the table at start up

    Remove ClearCollect over large tables from OnStart and point the gallery at the data source so paging and delegation apply. Keep collections for small reference data only, load them with Concurrent so they run in parallel rather than in sequence, and move anything not needed for the first screen out of the start up path entirely.

  11. Move genuinely non delegable work to the server

    Some requirements cannot be expressed as a delegable Power Fx formula: a real contains search across several columns, a filter on an aggregate, a grouping over the whole table. Those are server side problems. The supported answers are a Dataverse column maintained by a plugin or a flow, a custom API called from the app, or a saved Dataverse view that already encodes the filter. Choosing one of those is the fix; raising the row limit is not.

  12. Prove it at full volume and check a row past the limit

    Test against a table with production row counts, not a development table with two hundred rows, because delegation defects are invisible below the limit. Deliberately search for a record you know sits well past row five hundred in source order and confirm it is found. Then run Monitor again and compare the call count and durations against the reading you took in step one, so the improvement is a measurement rather than an impression.

Formulas to rewrite, before and after

Column and table names below are illustrative, so map them onto your own schema. The pattern in each row is the point: move the computation out of the predicate so what reaches Dataverse is a comparison between a column and a value.

Instead of

Filter(Accounts, TextInput1.Text in name)

The in operator as a substring test is not delegated. Power Apps downloads up to the row limit and scans it in the client, so the gallery is slow and misses matches beyond the limit.

Write

Filter(Accounts, StartsWith(name, TextInput1.Text))

Instead of

Filter(Contacts, Upper(lastname) = Upper(varSearch))

Wrapping the column in a text function turns the comparison into a client side expression and breaks delegation for the whole statement.

Write

Filter(Contacts, lastname = varSearch) with the case handling done once when varSearch is set, or against a column stored in a consistent case

Instead of

Filter(Cases, Customer.Country = "Germany")

Filtering on a column of a related record is evaluated in the client, because the related row is not part of the query being sent.

Write

Filter(Cases, CustomerCountry = "Germany") where CustomerCountry is a column on the case table kept current by a plugin or a flow

Instead of

ClearCollect(colOrders, Orders) in OnStart, gallery Items set to colOrders

The collection is capped at the data row limit, so it silently holds a fraction of the table, and the user waits for the whole download before the first screen renders.

Write

Gallery Items set to Filter(Orders, ownerid = User().Email && statuscode = varOpen), with the data source queried directly so paging applies

Instead of

SortByColumns(Filter(Accounts, statecode = 0), "name & city")

Sorting by an expression rather than a column is done in the client, which pulls the filtered set down to sort it and undoes the benefit of the delegated filter.

Write

SortByColumns(Filter(Accounts, statecode = 0), "name") or a single sortable column that encodes the ordering the business wants

Instead of

CountRows(Filter(Invoices, Year(createdon) = 2026))

Applying a function to the column inside the predicate breaks delegation, so the count is computed over whatever fits under the row limit and is simply wrong.

Write

CountRows(Filter(Invoices, createdon >= varYearStart && createdon < varYearEnd)) with both boundaries computed as variables first

Instead of

A text input bound directly to the gallery Items property

Every keystroke issues a query, so a seven character search produces seven round trips and the app appears to freeze while the user types.

Write

Delayed output enabled on the input, and the filter guarded so it only runs once a minimum number of characters has been entered

When the query genuinely cannot be delegated

Some requirements cannot be written as a delegable Power Fx formula, and pretending otherwise is how a non delegable filter ends up shipped with a comment next to it. These are the supported answers, each with what it costs you.

A column that holds the answer

The most common and the most boring fix. If you filter on something the app has to compute, compute it once on the server instead and store it: a denormalized value from the parent record, a status derived from three other fields, a normalized search key. A plugin or a Power Automate flow keeps it current, and the app filters on a plain column, which delegates. The cost is that you now own the logic that maintains it, so it belongs in a solution and under source control rather than in a note somebody kept.

A saved Dataverse view

Where the filter is fixed rather than driven by the user, a view already encodes it on the server, and pointing the app at the view moves the work to Dataverse without any Power Fx at all. This suits work queues and role based lists well, and it has the side benefit that the same definition is reused by the model driven app. It does not help when the filter has to respond to what the user types.

A custom API or a flow called once

For a genuine contains search across several columns, a query against an aggregate, or anything needing a real join, the honest answer is a server side call that returns the small result set the app displays. Called once with parameters rather than iterated per row, this is fast and fully correct. The cost is a component to build, test and version, which is the point at which the work stops being configuration.

A custom control for the list itself

Where the screen needs behaviour the gallery cannot express at volume, such as virtualized scrolling over a very large set, server side paging with a page size you control, or column level filtering in a grid, a custom control built with the PowerApps Component Framework is the supported route. It is a heavier answer than a formula rewrite and should be the last option, not the first.

Deciding the table is the wrong shape

Occasionally the right conclusion is that a screen listing five thousand active rows describes a process problem rather than a technical one. Rows that are all open because nothing closes them, or a single table doing the work of three, will produce slow screens no matter how well the formulas are written. That is worth naming before anyone spends a week on Power Fx.

If the answer turns out to be a custom control rather than a formula, the practical questions are whether a ready made component already does it and what building one involves, which we cover in using PCF controls in canvas apps and in the buy, build or customize decision guide. If the volume problem is really about getting the data into Dataverse rather than reading it back, that is a different exercise, covered in our Dataverse bulk import strategy.

How Solzet fixes an app like this

Canvas app performance work is part of our Power Platform delivery rather than a product we sell separately, so this is what it looks like when we do it.

We measure before we rewrite

A Monitor trace on the screen that is slow, at production volume, before any formula changes. It usually shows that the delegation warning everybody was looking at accounted for part of the wait, and that the row template, the start up sequence, or the payload size accounted for the rest. Rewriting formulas without that reading is how a week disappears into a change nobody can measure.

We treat delegation defects as correctness defects

Every open delegation warning on a table that can grow is a place where the app will one day show an incomplete answer without saying so. We close them rather than annotate them, and we test with a record deliberately placed past the row limit, because that is the test that would have caught it originally.

We are willing to say the screen is wrong

A gallery that opens on every row in the table is a design decision, and often nobody made it deliberately. Bounding the default set to what that person actually works on is frequently the largest single improvement available, and it costs less than the formula work it replaces.

We build the server side piece when the formula cannot win

A denormalized column maintained by a plugin, a custom API, a flow, or a PCF control for a list the gallery cannot serve at volume. These are things we build routinely as part of Power Platform delivery, so the decision to go server side is made on the requirement rather than on what the team happens to be able to build.

We ship it through proper solution lifecycle management

Separate development, test and production environments, changes made in unmanaged solutions and promoted as managed ones. A performance fix that exists only as an edit somebody made in the production app is a fix you will lose, and probably at the worst moment.

Certified engineers in one time zone

We deliver Dynamics 365 Customer Engagement and the Power Platform from a single hub in Yerevan, Armenia, at GMT+4, which overlaps Western European hours and reaches into the US morning. Our engineers hold Microsoft certifications including PL-200, PL-400 and PL-600.

The engagement models, the certifications and what a Power Platform developer actually covers are on our Power Platform and Power Apps development page. If you are still deciding whether this is work for your own team or for a developer at all, delegation is one of the walls named in our consultant versus do it yourself decision guide.

Frequently Asked Questions

Why is my Power Apps canvas gallery so slow with five thousand Dataverse records?

Usually because the formula in the Items property is not being delegated to Dataverse, so Power Apps downloads rows and filters them inside the app instead of asking Dataverse to filter. Since it will only download up to the data row limit, which defaults to five hundred, the gallery is both slow and incomplete. On real apps there are normally two or three other causes stacked on top: the whole table collected into a collection at start up, a LookUp inside the gallery row template that runs once per visible row, columns being retrieved that nothing on screen displays, and a search box that queries on every keystroke. Open Monitor and look at the actual network calls before changing any formula, because those four causes have four different fixes and only one of them is a delegation rewrite.

What is delegation in Power Apps, in plain terms?

Delegation is Power Apps deciding whether it can hand your filtering, sorting and counting to the data source instead of doing the work itself. When a formula is delegable, Power Apps translates it into a query, Dataverse evaluates it across the whole table however large it is, and only the matching rows come back. When a formula is not delegable, Power Apps has to retrieve rows and evaluate them locally, and it will only retrieve up to the data row limit. That is why delegation matters far more than it sounds like it should: it is not a performance setting, it is the difference between a question answered against your whole table and a question answered against an arbitrary first slice of it.

Should I just increase the data row limit to two thousand?

No, and it is worth being blunt about it because it is the first thing most teams try. It makes the app slower, because every non delegable operation now downloads four times as much data on whatever connection the user has. It does not fix correctness, because two thousand of five thousand rows is still a partial answer. And it hides the defect until the table grows, at which point the same bug returns with less context around it. The only defensible use is a table you can genuinely guarantee will stay small. While you are diagnosing, set the limit back to five hundred deliberately, because if the gallery contents change when you do, you have just proved which formula is not being delegated.

Which Power Fx functions are delegable to Dataverse?

The shape to remember is that simple comparisons between a column and a value delegate, and anything that computes does not. Filter, LookUp and Sort delegate with equals, not equals, greater than, less than and the And, Or and Not operators, StartsWith delegates on text columns, and the aggregates CountRows, Sum, Average, Min and Max delegate within documented limits. What does not delegate is the in operator used as a substring test, text functions such as Len, Left, Mid, Upper and Lower applied to a column inside the predicate, filtering on a column of a related record, sorting by an expression, and the table shaping functions AddColumns, GroupBy, Distinct and Ungroup. Microsoft revises this per connector, so confirm against the current delegation documentation, and trust the warning Power Apps Studio shows you as you type over any list you read on a web page including this one.

How do I write a delegable search box over a large Dataverse table?

Use StartsWith rather than the in operator, because StartsWith delegates against Dataverse text columns and the in operator used as a contains test does not. Keep the column on the left of the comparison and the search text on the right, with no functions wrapped around the column. Enable delayed output on the text input so the query runs once when typing pauses rather than once per character, and guard the filter so it does not run at all until two or three characters have been typed. If the business genuinely requires a contains search across several columns rather than a starts with search, accept that it is a server side requirement and answer it with a normalized search column maintained by a plugin or with a custom API, rather than by leaving a non delegable formula in the app and hoping the table stays small.

Is it better to use a collection instead of querying Dataverse directly?

For a large table, no, and the collection is often what made the app slow in the first place. ClearCollect over a five thousand row table is capped at the data row limit, so the collection silently contains a fraction of your data, the user waits through the whole download before the first screen appears, and the copy goes stale as soon as somebody else edits a record. A gallery pointed straight at the data source with a delegable filter loads a page of rows at a time and pages as the user scrolls, which is both faster to first paint and correct. Collections earn their place for small, stable reference data such as option lists and configuration rows, and for data the user is composing before it is saved.

Why does my gallery stutter while scrolling even though the filter is delegated?

Almost always something in the row template making its own request per row. A LookUp call to fetch a related value is the usual culprit, and two of them doubles the traffic. Image and file columns rendered in the row are another, since each one is a separate download. A delegated filter fixes the initial query but does nothing about work the template does per rendered row, which is exactly why Monitor is the right first step: a single slow query and a hundred fast ones look identical to the user and need completely different fixes. Resolve the related value from the lookup column already on the row, denormalize the field you need, or fetch the small related set once before the gallery renders.

What do I do when the query genuinely cannot be delegated?

Move it to the server rather than working around it in the app. There are four supported routes. Store the answer in a Dataverse column maintained by a plugin or a Power Automate flow, so the app filters on a plain column that delegates. Use a saved Dataverse view where the filter is fixed rather than user driven. Build a custom API or a flow that takes parameters and returns the small result set, called once rather than iterated. Or, where the list control itself is the constraint at volume, build a PCF control with server side paging. All four are more work than a formula change and all four are correct, which is the trade being made. Raising the data row limit is not on the list.

How do I prove the app is actually faster after the changes?

Take a Monitor trace before you start and another after, on the same screen, against a table with production row counts. Compare three numbers: how long the first query took, how many rows it returned, and how many separate network calls one scroll of the gallery produced. That last number is the one that usually collapses, because removing lookups from the row template and enabling explicit column selection tend to matter more than anything else on a list screen. Then run the correctness test alongside it: search for a record you know sits well past row five hundred in source order and confirm the gallery finds it. Speed and correctness are the same fix here, so verify both or you have only measured half of it.

Send us the screen that will not load

Tell us the table, the row count, and the formula in the Items property, and we will tell you whether it is a delegation rewrite, a payload problem, a start up problem, or a screen that was never bounded. Solzet is a Dynamics 365 Customer Engagement and Power Platform consultancy in Yerevan, Armenia, working with clients and Microsoft partners across Europe and the US.