Skip to main content
New tool CRON Expression Builder — preview next run times before you schedule Apex. Open the builder →
Diagram illustrating the bulk-safe pattern for iterating through a collection using a Salesforce Flow Loop element.
Flow

Master the Salesforce Flow Loop for Bulk Record Updates

Ever felt stuck trying to update a bunch of records at once in Flow? A Salesforce Flow loop handles the collection, and the bulk-safe pattern around it keeps you from breaking your org.

The short answer

A Salesforce Flow loop iterates through a record collection so you can change individual records while staying bulk-safe. Apply the field changes in memory with Assignment elements and run a single Update Records element after the loop completes, and you stay clear of the database governor limits.

Key takeaways Keep every DML operation outside the Flow loop, or you will hit governor limits and a System.LimitException. Pull records into an initial collection before the loop starts instead of querying inside it. Use Assignment elements inside the loop to change record fields in memory and add each changed record to a second collection. Run one Update Records element on that second collection after the loop has finished processing. Add fault paths to the Update Records element after the loop so you can see which record failed and why, such as a validation rule error.

Why you actually need a Salesforce Flow loop

If you've spent any time building automation, you've probably hit a wall where you need to update more than one record at a time. That's exactly where a Salesforce Flow loop comes into play. It's the tool we use when we have a collection of items (a list of Contacts or Opportunities, say) and we need to look at or change each one individually.

Think of it like a conveyor belt. Your "Get Records" element dumps a pile of boxes on the belt, and the loop picks them up one by one, lets you do something to them, and then puts them back. I've seen teams avoid loops because they look intimidating, but once the pattern clicks, it's easily the most useful tool in the kit. It's how we keep automation efficient and bulk-safe.

A Salesforce Flow Builder diagram of the bulk-safe loop pattern, with the Update Records element sitting outside the loop to avoid governor limits.

A Salesforce Flow Builder diagram of the bulk-safe loop pattern, with the Update Records element sitting outside the loop to avoid governor limits.

Building a bulk-safe Salesforce Flow loop pattern

Most people fail with loops because they try to save their changes inside the loop. Don't do that. Put an "Update Records" element inside your Salesforce Flow loop and you will hit governor limits faster than you can say "System.LimitException". Salesforce hates it when you talk to the database over and over in a tiny window of time.

Instead, we use a specific pattern to handle bulk record processing. We grab our records, loop through them, make our changes in memory using an Assignment element, and then add those changed records to a new collection. Only after the loop is totally finished do we hit that single "Update Records" button. It's cleaner and faster, and it won't break your org the moment you have more than ten records to process.

A real-world example: the 90-day follow-up

Here's a scenario I run into all the time. Your sales VP wants a checkbox called Needs_Follow_Up__c checked on every Contact related to an Account if they haven't had any activity in 90 days. A simple update won't do it, because you have to check the date on every individual person. You need a loop.

You start with a "Get Records" to find all Contacts where the AccountId matches your current record. That gives you your initial collection. Before you start wiring up the logic, keep data integrity in mind. You want to be sure you're only updating what actually needs to change.

The configuration logic

Under the hood, the Salesforce Flow loop lays out like this:

  • Get Records: pull all Contacts for the Account into collectionContacts.
  • Loop: iterate through collectionContacts using a loop variable, call it currentItem.
  • Decision: is the LastActivityDate older than 90 days?
  • Assignment 1: if yes, set currentItem.Needs_Follow_Up__c to True.
  • Assignment 2: add currentItem to a new collection variable called contactsToUpdate.
  • Update Records: after the "Last Item" path of the loop, update the contactsToUpdate collection.

// The logic flow
Loop: For each Contact in collectionContacts
  Check: Is LastActivityDate <= 90 days ago?
    Yes: 
      Assign: currentItem.Needs_Follow_Up__c = True
      Assign: Add currentItem to contactsToUpdate
    No: 
      Continue to next item
End Loop
Update: contactsToUpdate

Common mistakes that break your Salesforce Flow loop

One thing that trips people up is forgetting to initialize their collections. Try to "Add" a record to a collection variable that hasn't been set up properly and the Flow might just cough and die. Make sure your "To Update" collection is ready to receive data. Keep an eye on your record counts too. If you're trying to loop through 5,000 records in a single Flow, you're probably better off using Apex or a scheduled batch.

The other common trap is over-complicating the logic. Sometimes you don't even need a loop anymore. The Transform element can often handle simple mappings or counts without the overhead of a traditional loop. I tell my junior devs the same thing every time: the fact that you can use a loop doesn't mean you should. Look for the simplest path first.

Pro Tip: Use Fault Paths on your Update elements outside the loop. If one record in your collection fails, maybe because of a validation rule, the whole update fails. You'll want to know why that happened rather than just seeing a generic "Flow Error" email.

Key takeaways

  • Never, ever put a DML operation (Create, Update, Delete) inside a Salesforce Flow loop.
  • Use a "Get Records" element to build your initial collection before the loop starts.
  • Create a secondary "Update Collection" to hold your modified records.
  • Run a single "Update Records" element after the loop finishes its work.
  • For massive datasets, look at a Scheduled Flow or Apex Cursors instead.

Loops are the bread and butter of serious Flow building. They let you handle complex logic that a simple record-triggered update just can't touch. Stick to the "Get-Loop-Assign-Update" pattern and you'll stay well within your governor limits while building automation that actually scales. Next time you're staring at a requirement that involves multiple records, don't sweat it. Grab a loop and get to work.

Frequently asked questions

Why should you avoid DML statements inside a Salesforce Flow loop?

An Update Records element inside a loop makes repeated database calls in a short transaction window. That breaches Salesforce governor limits quickly and throws a System.LimitException error.

How do you bulkify record updates in a Salesforce Flow loop?

Query your records into an initial collection with Get Records, loop through the items, and apply the field changes in memory with Assignment elements. Add each modified item to a new collection variable and run one Update Records element on that collection after the loop ends.

When should you not use a Flow loop?

Skip the loop when the Transform element can handle a simple mapping, or when the dataset is too large for a standard Flow to process safely, such as a collection approaching 5,000 records.

Why should you add a fault path to an Update Records element outside a loop?

If one record in the collection fails its update because of a validation rule or a data error, the whole update fails. A fault path captures the details of that failure instead of sending a generic flow error email.

Newsletter

One email every Tuesday

New guides, tool updates, and the release-note changes that break things.

No spam. Unsubscribe in one click.

Comments

Loading comments...

Leave a Comment