Avoid Flow Limits
Learning Objectives
After completing this unit, you’ll be able to:
- Identify the per-transaction limits of flows.
- Avoid accessing large numbers of records that can exceed flow limits.
- Avoid loop practices that can exceed flow limits.
Stay Within Your Limits
Flows are very powerful, but there are limits to that power. Remember, Salesforce runs on a multitenant infrastructure, which means your org shares server resources with other orgs. To prevent one org from affecting the other orgs on the server, Salesforce limits flows and code in a number of ways. Salesforce calls these governor limits.
While flows have a number of considerations for specific scenarios and conditions, the per-transaction limits are the most important limits to be aware of. They apply to every flow, they’re easy to exceed if you’re not careful, and they can bring any flow to a crashing halt without warning. They’re called “per-transaction” because they limit the number of things that can occur within a single transaction.
So what is a transaction, exactly? To understand transactions in flows, think about two trains traveling a standard route. Train one is an express train, so it goes from point A to point B without stopping. Train two makes stops to pick up more passengers along the way. Similar to train one, a flow might run uninterrupted in a single transaction. Or, like train two, a flow might come to a Screen element or one of the Wait elements (Wait for Conditions, Wait for Amount of Time, or Wait Until Date) and stop. That stop ends the current transaction. After the stop, a new transaction starts. It’s all one flow, one train ride, but it’s broken into multiple transactions by any stops it makes.
Let's take a look at some example scenarios of how transactions are divided around flows and other automation. Click through the scenarios using the Next and Previous buttons.
Here are some of the most common per-transaction limits encountered in flows.
Type of Limit
|
Description
|
Limits
|
---|---|---|
SOQL A Salesforce Object Query Language (SOQL) query is a request to fetch specific record data from your Salesforce org’s database.
|
SOQL queries are caused by:
Each element causes one query. |
|
DML A Data Manipulation Language (DML) statement is a command that adds, edits, or deletes records in your Salesforce org’s database.
|
DML statements are caused by:
Each element causes one query. |
|
CPU |
The time that a transaction takes to run. |
10 seconds of CPU processing time per transaction |
Those are some pretty big numbers! You might be thinking, “There’s no way I’ll ever come close to hitting those limits.” But it’s easier than you think. Here are some common ways that flow creators reach these limits and what you can do to prevent that.
Large Numbers of Records
There are several ways for the number of records in a single object to get into the tens of thousands. One way is by uploading large lead databases. Another is by gradually accumulating a few thousand accounts, each having a handful of contacts. It’s okay to have a lot of records; just having a large database doesn’t cause flow errors. But to prevent your flows from hitting SOQL and DML limits, you should limit the number of records that your flows work with.
To avoid hitting SOQL and DML limits, use filters to minimize the number of records your flow retrieves and updates. Let’s look at the Uncheck Contacted This Quarter flow that came with the package you installed earlier in this badge.
You can’t configure a schedule-triggered flow to run quarterly, so this schedule-triggered flow runs daily. A Decision element verifies that the current date is the first day of the quarter, and if it is, an Update Records element unchecks the Contacted This Quarter checkbox on every contact in the org. It even unchecks the field on records where the field is already unchecked. But this flow will fail if the org contains more than 10,000 contacts. Let’s update the flow so that it only updates contacts where Contacted This Quarter is checked.
- In the Uncheck Contacted This Quarter flow, edit the Uncheck Contacted element.
- In the Filter Contact Records section, change Condition Requirements to Update Records to All Conditions are Met (AND).
- For Field, select Contacted This Quarter.
- Make sure Operator is set to Equals.
- For Value, select $GlobalConstant.True.
- Save the flow.
This change should reduce the number of updated contacts below the 10,000 record limit. Plus, because the flow is doing less work, it runs faster!
You can set similar filter conditions on Get Records elements and on the Start element of a record-triggered flow.
Loops
Loops are powerful elements that allow your flows to iterate through a collection of records, running each record through other elements, one record at a time. Those elements run once for each record in the loop, so if the loop is processing more than a few records and contains a Get Records, Create Records, Update Records, or Delete Records element, the loop can quickly reach the 100 SOQL query limit or the 150 DML statement limit.
To avoid hitting these limits, don’t put Get Records, Create Records, Update Records, or Delete Records elements inside a loop. Instead, place them outside the loop.
- Get Records: Before the loop
- Create Records, Update Records, and Delete Records: After the loop
Let’s look at an example. The Clone Opp with Products flow clones an opportunity and its products.
This flow fetches an opportunity’s values (1), uses an Assignment element (2) to make some changes to the record’s values, then creates a clone (3) with those changed values. The flow has to do the same thing with each of the opportunity’s products, so it uses a Loop element (4) to run through each of the original opportunity products. The loop also uses an Assignment element (5) to make changes, setting each opportunity product’s OpportunityId to the clone’s ID. (Don’t worry, the flow doesn’t save these changes to the original opportunity products.)
But after that, the loop uses a Create Records element (6) to create a new opportunity product. That Create Records element runs one DML statement for every product in the loop. The flow will fail if the transaction runs over 150 DML statements, which can easily happen if the opportunity has a lot of products, or if the flow is part of a bigger transaction with other DML statements. Those scenarios might be unlikely, but they are possible. Wouldn’t it be a lot safer to reduce all of those DML statements to just one?
Let’s move the Create Records element out of the loop. Create a record collection variable to store the altered opportunity product clones. Then, update the Assignment element so that it adds the current opportunity product’s altered values to that new collection. Finally, the Create Records element can create all the collection’s clones after the loop.
- In the Clone Opp with Products flow, create a variable:
- API Name:
newOppProds
- Data Type: Record
- Allow multiple values (collection): selected
- Object: Opportunity Product
- Edit the Set Current Line to New Opp element and add an assignment line:
- Variable: newOppProds
- Operator: Add
- Value: Current Item from Loop Loop Opp Products (Select this record variable, then click elsewhere to select the whole variable instead of just one field.)
- Select the Create Opp Prod element.
- Select Cut Element.
- On the After Last path, hover over . When it changes to click the icon.
- Edit the Create Opp Prod element and change these settings:
- How Many Records to Create: Multiple
- Record Collection: newOppProds
- Save the flow.
Now, the flow loops through each opp product (4), and on each one, the Assignment element (5) changes the current opp product’s values and adds those changed values to the newOppProds collection. Then the Create Records element (6), now located after the loop, creates all the opp products in the newOppProds collection. And all in one DML statement!
Flows Started By Other Automation
If a flow is started by another automation, it runs as part of that first automation’s transaction. Because the governor limits mentioned above are all per-transaction, anything done by the other automation counts toward all those per-transaction limits as well.
For example, Pyroclastic’s org has a complex Apex class that takes 9 seconds of CPU time to do its work. Then the Apex class calls an autolaunched flow. The flow takes 2 seconds of CPU time to run, so the flow fails (along with the Apex class) because the full transaction exceeds the 10 second limit. The flow would also fail if the Apex class contained too many SOQL queries, DML statements, records retrieved, or records affected.
The best way to avoid this limit is to make sure your automation is as efficient as possible. If an Apex class takes 9 seconds of CPU time to run, there’s a good chance that it can be simplified or improved. (Nine seconds is a long time for an Apex class!) The same goes for any flow that takes 9 to 10 seconds. If all else fails, add one of the Wait elements (Wait for Conditions, Wait for Amount of Time, or Wait Until Date) to start a new transaction.
Knowledge Check
Use this check to test your knowledge on avoiding flow limits.
This knowledge check is not scored—it's just an easy way to test your knowledge. To use it, read the question, then click the letter of the item that you determine correctly answers the question. Some questions may have more than one correct answer. Click Submit to check your answer for correctness. Feedback is provided for each answer chosen. When you've answered all the questions correctly, you can review all of the answers or retake the knowledge check.