Bulk Update Power Apps Data Without Loops
Replace slow ForAll+Patch patterns with a single Patch call that handles multiple rows in one network round trip.
Every Power Apps developer eventually faces the “many‑record update” problem: a gallery of items whose status changes via toggles, checkboxes, or dropdowns, and one button that should persist every change back to the datasource. The obvious approach—loop over a collection with ForAll and call Patch for each row—works, but it often feels slow, especially when dozens of records are involved.
You can skip the loop entirely. The Patch function accepts a record or table as its second argument. When you pass a table, Power Apps sends one batch request instead of many individual requests. The result: updates that feel nearly instantaneous, even with hundreds of rows.
This article walks through a realistic scenario (a classroom attendance tracker, recast as an inspection app to keep things fresh), compares the two methods side‑by‑side, and includes a micro‑benchmark to see the actual difference.
Scenario: Audit Inspection Log
Imagine you manage a warehouse and need to quickly mark which pallets have been inspected. The SharePoint list InspectionLog looks like this:
| Field Name | Type | Notes |
|---|---|---|
| ID | Auto‑number | Primary key |
| PalletNumber | Text | Unique identifier for a pallet |
| PassedInspection | Yes/No | Inspected? (default No) |
| InspectorComment | Text | Optional note |
We’ll build a canvas app that loads the list into a collection, displays a gallery with a toggle for PassedInspection, and then offers two “submit” buttons: one using the batch Patch and one using a ForAll loop.
Step 1 – Set Up the Data Source and Collection
In Power Apps Studio, add the InspectionLog list as a data source. In the App.OnStart property, load the data into a collection:
ClearCollect(colInspections, InspectionLog)
The gallery will bind to this collection so changes are local until you commit.
Place a Vertical Gallery on the screen and set its Items property:
colInspections
Inside the gallery, add a Label for PalletNumber and a Toggle that lets the user flip the inspection status. Configure the toggle’s Default property to reflect the current row value:
ThisItem.PassedInspection
When the user toggles, we need to update the local collection immediately. Use the OnCheck / OnUncheck events (or OnChange):
Patch(colInspections, ThisItem, {PassedInspection: Toggle1.Value})Do the same for the OnUncheck or simply use OnChange if you prefer:
Patch(colInspections, ThisItem, {PassedInspection: Toggle1.Value})Now the collection always matches the UI state, but nothing is written back to SharePoint until the user clicks one of the submit buttons.
Step 2 – The Batch (Fast) Write
Create a button named btnSubmitFast and set its OnSelect:
Patch(InspectionLog, ShowColumns(colInspections, "ID", "PassedInspection"))
Explanation:
ShowColumnsstrips the collection down to only the fields needed: the unique identifier (ID) and the column(s) to be updated (PassedInspection). This avoids sending read‑only or calculated columns that could cause errors.- Because the second argument is a table,
Patchperforms one bulk update. Power Apps generates a single network call that updates all matching records.
The matching is done by the primary key (ID). Any column that appears in the passed table with a name identical to a column in the data source is written.
The collection must contain a column that matches the data source’s primary key (usually ID). All other supplied column names must match the data source exactly. If they don’t, the update silently fails for those columns.
Step 3 – The Loop (Slow) Write
For comparison, add a second button named btnSubmitSlow. Its OnSelect uses the traditional approach:
ForAll(
ShowColumns(colInspections, "ID", "PassedInspection"),
Patch(InspectionLog, ThisRecord, {PassedInspection: PassedInspection})
)This loops over each row and calls Patch individually. Power Apps sends n separate requests, one for each record. The overhead of establishing and tearing down those connections accumulates quickly.
Step 4 – Speed Comparison (Micro‑benchmark)
To measure the difference, add a few global variables and a couple of labels.
Add the following to your App.OnStart (or into a separate OnVisible of the screen you use for testing):
Set(varToggleDefault, false); // used to flip all toggles at once Set(varDurationFast, 0); Set(varDurationSlow, 0);
Change the Toggle Default inside the gallery to use the variable instead of the record value (this lets us flip all toggles to the opposite state in one go):
varToggleDefault
Now replace the OnSelect of the fast button with:
// Record start time Set(varStartFast, Now()); // Batch update Patch(InspectionLog, ShowColumns(colInspections, "ID", "PassedInspection")); // Calculate elapsed ms Set(varDurationFast, DateDiff(varStartFast, Now(), Milliseconds)); // Flip all toggle values for the next test Set(varToggleDefault, !varToggleDefault);
Similarly, update the slow button’s OnSelect:
Set(varStartSlow, Now());
ForAll(
ShowColumns(colInspections, "ID", "PassedInspection"),
Patch(InspectionLog, ThisRecord, {PassedInspection: PassedInspection})
);
Set(varDurationSlow, DateDiff(varStartSlow, Now(), Milliseconds));
Set(varToggleDefault, !varToggleDefault);Finally, place two Label controls on the screen to show the durations:
Text(varDurationFast, "[$-en-US]0") & " ms"
Text(varDurationSlow, "[$-en-US]0") & " ms"
Run the app. Click the Fast button, then the Slow button (or vice‑versa). For a dataset of, say, 50 rows, you will see a dramatic difference: the batch method often completes in under 200 ms while the loop method can take several seconds.
Performance Implications and Delegation
The Patch‑with‑table approach does not change delegation behaviour—the actual bulk update happens server‑side after Power Apps sends the entire table. Because the collection is already on the client, there are no delegation limits to worry about for this particular operation. The benefit comes entirely from reducing the number of HTTP round trips.
Very large collections (thousands of rows) might still cause performance or memory issues. The batch Patch sends the whole table in the request payload, so test with realistic data sizes. In my experience, a few hundred rows is no problem; beyond 1 000 you should consider paging or server‑side operations.
Common Mistakes and Troubleshooting
Missing primary key column
If the collection does not contain the ID column (or whatever the data source uses as a unique identifier), the update will not match any records. Always include it via ShowColumns or by retaining it from the initial Collect.
Read‑only or auto‑calculated columns
Passing a column that cannot be written (e.g., a computed column, a Title field that is auto‑generated) will cause the whole Patch to fail. The safest practice is to explicitly select only the columns you intend to change with ShowColumns.
Data source limitations
Not all data sources support batch Patch. The method works with Microsoft Dataverse, SharePoint, SQL Server (via connector), and many others. Check the documentation for your specific connector. For unsupported sources, the function may fall back to a loop—or throw an error.
Inconsistent casing Column names are case‑sensitive in some connectors. Ensure the case in your collection matches the datasource exactly.
Recommendation
If your app updates more than a handful of records at once, always prefer the Patch(Datasource, Table) pattern over a ForAll loop. It is cleaner, faster, and reduces the load on both the network and the data source.
For read‑heavy scenarios (e.g., marking 200 items as “read” in a notification app), the speed difference is immediately noticeable to users. For write‑heavy operations like bulk‑editing vacation requests or inventory counts, it can turn a frustrating wait into an instant save.
References
- Original technique article: PATCH Multiple Records In Power Apps 10x Faster by Matthew Devaney.
- Microsoft documentation –
Patchfunction (batch syntax): placeholder – consult official Power Apps docs for latest. - Microsoft documentation –
ShowColumns,Collect,ForAll.
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.