Tutorials/Power Apps/Bulk Update Power Apps Data Without Loops
Power Appsintermediate

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.

NA
Narmer Abader
@narmer · Published June 3, 2026

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 NameTypeNotes
IDAuto‑numberPrimary key
PalletNumberTextUnique identifier for a pallet
PassedInspectionYes/NoInspected? (default No)
InspectorCommentTextOptional 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:

powerfxOnStart of the app
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:

powerfxGallery Items
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:

powerfxToggle Default
ThisItem.PassedInspection

When the user toggles, we need to update the local collection immediately. Use the OnCheck / OnUncheck events (or OnChange):

powerfxToggle OnCheck
Patch(colInspections, ThisItem, {PassedInspection: Toggle1.Value})

Do the same for the OnUncheck or simply use OnChange if you prefer:

powerfxToggle OnChange (alternative)
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:

powerfxFast submit – batch Patch
Patch(InspectionLog, ShowColumns(colInspections, "ID", "PassedInspection"))

Explanation:

  • ShowColumns strips 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, Patch performs 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.

Important

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:

powerfxSlow submit – ForAll + Patch
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):

powerfxSetup speed-test variables
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):

powerfxToggle Default (benchmark)
varToggleDefault

Now replace the OnSelect of the fast button with:

powerfxFast button with timing
// 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:

powerfxSlow button with timing
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:

powerfxLabel for fast duration
Text(varDurationFast, "[$-en-US]0") & " ms"
powerfxLabel for slow duration
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.

Collection size

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 – Patch function (batch syntax): placeholder – consult official Power Apps docs for latest.
  • Microsoft documentation – ShowColumns, Collect, ForAll.