How To Bulkify Your Salesforce Flows
Salesforce Flows have become increasingly popular, and in many cases have the power to replace Apex code. But as our favorite superhero reminds us… “With great power comes great responsibility.” Let’s take a look at how we can bulkify our flows so they run efficiently, and do not exceed the limits Salesforce applies. We’ll also take a deep dive into Apex Actions to understand more about the order of events, and where we need to provide nullification
What is Bulkification, and why is it important?
Bulkification is a design pattern for using system resources efficiently. For example, at the store you purchase eggs, milk, and bread all at the same time, instead of making separate trips for each item. In the same way, when requesting Salesforce to use system resources, such as updating records, it is best to bulkify this request by providing Salesforce a list (or collection) of records to update.
Because Salesforce is a multi-tenant environment, system resources are shared across all users on that server. To ensure no one user is consuming more than their fair share of system resources, Salesforce has imposed system limitations (called governor limits) based on the request made.
Can Salesforce bulkify my flows for me?
Great News! Yes, many elements of your flows that consume system resources will be automatically bulkified when processing multiple records at a time. Salesforce will wait until all flow interviews have reached the same flow element and then process just one request for all records at the same time. We will take a look at how this works with Apex Actions later in the post.
When do I need to Bulkify my flows?
While Salesforce can provide bulkification across multiple flow interviews. Each individual flow will still need to respect the governor limits set by Salesforce. The easiest way, and most common method, to prevent your flows from exceeding governor limits is to only use system resources outside of any loops. While performing a DML operation inside a loop might not be an issue when updating just 5 or 6 records, your flows will not be scalable when there are 500 records to update. A superhero admin knows it’s best to take the time to write a scalable flow now for “truth, justice, and a better tomorrow.”
In the flow above, a collection variable is created to store the related Contacts that need to be updated. Each time the loop iterates, an updated record is added to the collection variable. Then after the loop completes, the update element updates all the records stored in the collection variable at the same time. Now this flow is only consuming 1 of your 150 DML operations to update the records, instead of using a DML operation on each record that needs to be updated.
What about Apex Actions, do these need to be bulkified too?
Odin’s Beard! As a superhero developer or admin, we wouldn’t want to leave any flow element behind. If you have read about flows, you have likely come across documentation that says,
“A flow interview runs for each record in the batch.”
On the surface, this sounds like bulkification wouldn’t be required since each record is processed individually. But Salesforce will try to conserve system resources whenever possible, and even though separate interviews are running, any Apex Action will be automatically bulkified.
An analogy I like to use is an airplane and passengers. We can think of an Apex Action like a flight from Los Angeles to San Francisco. To conserve system resources, Salesforce is only going to make one trip from LA to SF, and each record that needs to be updated is like a passenger on that flight. That record will have its own interview path up until it’s time to board the flight (start the Apex Action). The invocable Apex Action will then take off and process all the records at the same time. When the Apex Action is finished (the flight lands) all the records (passengers) can resume their own individual interview path. This can be a little complicated, so let’s see it in action.
The Flow above is a Scheduled-Triggered Flow, so it’s likely multiple records will be processed at the same time. A flow interview will run for each record until they reach the Apex Action. At which point all the records will be processed by the Apex Action at the same time before continuing on their own flow path. *Note: legacy Apex Actions using the Process.Plugin interface do not support bulk operations, and will run per flow interview.
What does this mean for me?
Because Salesforce is going to bulkify your Apex Action the Flow Inputs and Outputs will always need to be a list, to allow multiple input parameters to be processed at the same time. To bulkify your Apex code, it is a good practice to loop through all the Flow Inputs and wait to perform any DML operations until after the loop completes. This will allow the same Apex Method to be used in a variety of contexts without issues.