Flow: How To Use “Loop”
Loop is a very common concept in all programming languages, but I find the flow Loop element very unique in Salesforce. To separate the two, let’s call the loop in real life “Repetition”, and the Loop element in Salesforce “Loop”.
In a real life, there are two scenarios when repetition is needed.
- Repeat the same actions for every item in one collection.
- Repeat the same actions for a specific number of times. (Run this action for 5 times)
In Salesforce, the Loop can only achieve the first scenario. However I will show you how to handle the second without using a Loop in this article.
Scenario 1 – Repeat By Loop Element
Step 1 – Create a collection variable
First you need to have a collection variable. The most common way is by using Get Records with multiple records return. For example, here I got all the accounts with rating = Hot.
Step 2 – Put in the Loop element
Assuming I want to create one task for each hot account, I will need to use the Loop. For the configuration, you only need to enter which collection variable you want to loop through, and whether you want to start from the first or the last item (Usually useful for date-related operations)
At the bottom there is a long paragraph which looks complicated, but basically you can think of Loop as “For each account, do ____ and ____”. In order to take out each account from the collection, the system will create a new variable – Current Item from Loop XXX. Then later in the loop, you will need to use this variable to execute the actions.
Step 3 – Add actions inside the loop
After I have the loop, I need to add actions that will run for each record. Here I want to create new tasks for each account. As reminded by the community, the best practice is to store the new records in a collection variable and then use the Create Records only once. First, we need to create a record single variable and a record collection variable.
When I am assigning the Related Id, I can see there is a “Current Item from Loop – For Each Account”. By clicking it, I can get the Account Id for each item, and then create a task associated with it. Also, I put all actions in one assignment here just to demonstrate, but please remember to move the add to collection action to another assignment!
Then you connect the loop with the action. You will see two options – For each item in the collection and After last item in the collection. Choose the first one and we will talk about the second in step 5.
Step 4 – IMPORTANT! Close up the loop!
This is the most unique part that differentiate the repetition in Salesforce and in other programming languages. After you finish the actions, you have to close the loop up manually!!! This is very very very important, as if you forget to do so, your flow stops at the first iteration.
Here we can conclude, the Loop element is not a complete loop actually, but a function that helps to take out each item in one collection by order (It confused me pretty well in the beginning).
Step 5 – Add actions after the loop is done
If you want to continue your flow, you have the option “After Last Item”. Drag it out from the Loop element, and then your flow will go on after all items have been looped through. Here we need to add the Create Records at the end, so the system and create all tasks at once.
Then we finish with how Loop should be set up and utilized. If you want to know how to run the same repetitions unrelated to collections for specific times, check out this article!
Check Out How Loop Can Be Used In Real Cases!
Use Case: Collection Sort To Calculate Upcoming 3 Opportunities
Use Case: Update Order and Order Product Dates Quickly
Use Case: Get a List of Names of Related Records to a Field
Use Case: Update All Related Contacts (Account Contact Relationship)
You’ll want to bulkify your loop “create record” action by adding the new records as a record variable then adding the new record to a collection of records to insert/update in a single DML action. Also, creating records in a loop is not best practice and increases the chance of hitting platform limits.
Great point Anthony. I will make sure to post another article to explain how this action can be done. Thanks!
Hi again, I see that many are having the same concerns, so in order not to mislead people I have edited the post right away. Thanks for the feedback.
Hello, let me ask you this… How do you force-restart a loop? If you exit the loop midway, say after record #5, do some steps, then come back to this loop – it will resume from record #6. Which is great, but what if I specifically want it to start over from the beginning of this collection?
A good example is a scenario with a nested loop. So I have 2 loops: X and Y (which is nested inside of X). I start by picking record #1 from X, “For Each Record” it goes to 2nd loop Y and picks record #1 from there. It does some validations, finds no match, and goes to pick record #2 from Y. Does some validations, it meets the criteria, we do some steps on it and then go to pick up record #2 from the first loop X. At that point, I want loop Y to start from the beginning of the collection. Instead loop Y will resume with record #3 because record #2 was the last one it processed. How do you force it to start over?
Hi Nick, very interesting question. The only way I know to force start the inner loop is to put it in a subflow, which could be a good option if you have many iterations in the inner loop. Otherwise if the iterations are not too many, you can let the inner loop finish all iterations so it will restart.
There is an idea we can upvote to support the break and continue feature: https://trailblazer.salesforce.com/ideaView?id=0873A0000003SCpQAM
Are there limits on how many records can be updated?
I have a flow working fine until it encounters 1000+ records to update. I set batch size to 100, then 50 then 10 and now 2. No luck
Hi John, yes there is some limits. You can check the governor limit article for details. However if you are only updating ~1000 records, I suspect you are hitting the element limit (There can only be 2000 elements executed for 1 flow interview)
If you want to update a huge batch of data, first try to see if you can use only one Update Records element (This can update all records that meet the same criteria with the “same” values). Otherwise you might have to go with schedule-triggered flow. Hope this helps!
So, I recreated this (the bulkified version) in a scheduled-Time-flow, to run every night. It looks to see if that day there are contracts that will expire in X days. The “Get records”element filters the contract on that expiration day and then only adds them to collection if they come through the filter.
Then in the loop, it creates field values for each case record it needs to create later on, then adds tose records to the new case collection.
After the loop ends, it creates cases based on the data in the new cases collection. One case related to each expiring contract.
The flow is triggered every night, getting contract records that expire shortly and then creating cases for them.
In debugger this works perfectly. If there are two expiring contracts, it creates two related cases and that’s that. WAD.
But in runtime, everyday it seems to start the flow over and over again, creating thousands of cases every day, all related to the same contracts that the “get record” element picked up. So I end up with expiring contracts that each have thousands of related cases that are created by this flow.
Is this method for record creation maybe not suitable for automatic daily runs? Am I missing something here?
I think an extra filter in the “Get records” element that checks if a relted cases for the expiration is laready related to the contract. But that feels like a possible solution for a problem I should not be creating in the first place.
So… Anyone any thoughts?
Hi Mark, schedule-triggered and record-triggered flows are quite special. They are bulkified, meaning that you can build the flow as if it’s for one record, but the flow will batch all the records that meet the criteria. At the same time in debug mode, the system only debug on 1 record. So assuming you have 10 contacts – in debug it runs on 1 contact which get 10 contacts and create 10 cases, but in the actual flow, it will run on 10 contacts which get 10×10 contacts and create 100 cases. I believe this is what happened to your flow.
So try to build the flow as if there is only one contact and only one case needs to be created. Then you should find the flow run properly when it’s activated. Hope it helps!
Hello Melody, just wanted to thank you for this post. I frequently link to it on the Trailblazer community when helping other users understand flow loops!