Flow Basics | Bulkify Flows to Insert/Create Multiple Records

In this post, I will be showing how to Bulk Insert Records using a Flow in Salesforce. We will Bulkify Flow to create Multiple records of an object at once instead of creating them one by one inside a Loop. 
Bulkify Flows to Insert/Create Multiple Records in Salesforce


How to Insert Multiple Records in Flow (At Once)

Flow has a Create Records Element which can be used to Create/ Insert new Records for any object. Creating a single Record is straight forward and there is not much to worry about in terms of best practices. 

The tricky part is Creating/Inserting Multiple Records for a particular object at once. At least, it proved a bit tricky for me when I tried this for the first time. There are two ways I thought of doing it initially :

1. Using Create Record Element multiple times in a Flow. Either inside a Loop or otherwise.
2. Using a Single Create Record Element and pass all the new records to be created and create them at once.

Obviously, second way is the correct way!

NOTE : This article is showing Flow Bulkification while creating Multiple Records in a Salesforce Flow. If you want to see how to Bulk Update in Flows or Mass Update Records in a Flow then checkout this article for better understandingMass Update Records in a Flow

Never Use Create Records Element inside a Flow Loop. Never!

Before we move ahead, please remember this point always. Because, an easy way to Create/Insert multiple records is to use the Create Records Element inside a loop. But don't do it.

Never use a Create Record Element inside a Loop. Salesforce Governor Limits don't like it much and if we are dealing with a large volume of records, there's a good chance we will hit the limits. 

This kind of design is not scalable and will fail once we have more records to deal with and if there are any other automations(like triggers, flows etc.) running/getting fired within the same transaction. 

How to Avoid using Create Records Element inside Loops in Flow 

The best way to avoid using Create Record Element inside a Loop is to actually create a New Collection Variable of type Record to hold/store all the new records to be created and use a single Create Records Element at last for this Record Collection Variable.

This is called Bulkification of Flows or a Bulkify (Bulkified) Flow

Please Note: In order to try and showcase a Specific Use Case, I may have overlooked some of the best practises related to Flow Development in this article. Please make sure to follow these in real world scenarios and projects. Check some really important ones below.


Sample Scenario / Use Case

We need a screen Flow on Account Record Page. This Flow will be used create a new case for every contact for the Account. 

For every contact on an Account, we need to create a new Case. All Cases have to be created in one go.
Every case (one for each contact) should have the same Account Id i.e. should be associated to the same Account. Case Subject should be equal to Contact Name and Case Type should be Internal.

Note: This is a very basic scenario to explain the overall logic behind this Bulkification process. Same logic and design can be applied in any other scenario depending upon the actual requirement or use case.

Sample Data (Inspired by my latest favorite Netflix Series 'Dark')

Account Name : Dark
Contacts : Ulrich, Martha,Jonas, Magnus, Claudia

On click of Finish button in Screen Flow, system should create five Cases, one for each contact. All these Cases should be associated with Parent Account (Account : Dark)  and their subject should be equal to respective contact's name and origin equal to Internal.

Overall Flow Design
Bulkify Flows to Insert/Create Multiple Records in Salesforce

Solution and Explanation

Our Flow is a basic Screen Flow. It will be placed on Account Record page, so we can pass Account record directly to the Flow (Summer'20 feature) instead of only Account Id.

Please Note: The Screen Element in this Flow will have no real purpose. It will just be used to show the Flow on Account Page and provide a Button for the user to Fire the Flow. 

So First step is Create an Input Record Variable of type Object (Account) to pass Account Record from Page to Flow. I named this variable as AccountRecord. When we will save and activate this Flow and put it on a Lightning Record Page of Account, we will see this Variable name with an option to pass data into it from Page. 

Next, based on Account, we will Get all related contacts for that Account using Get Element in Flow. For our example, we will get those 5 records as per our dummy data.


----------------------------------------------------
Tip: Always add a Decision Element after a Get Record Element to check if any records were returned or not. Flow should only execute further, if Get Records found any records.
----------------------------------------------------
Now, we will have to Loop over these Contacts one by one and create a case for each of them.

Here comes the tricky part. When we will loop over contact one by one, how can we avoid to use a Create Record Element within the Loop. 
There are two steps needed to achieve that. Before, we can Loop over Contacts, we need to have two more Variables as shown below.

Create a Blank Collection Variable to hold/store all new Case Records to Insert

The first step is to create a New Variable of type Record (Object type Case)
Enable it to have Multiple values (Collection). This variable will be our final list/collection of new Records (Cases) that we need to create/Insert at last. The name is "CasesToCreate"

Let's refer to this Collection Variable as Tray of Cases for better representation. When we create this variable, the Tray(Collection) is empty and has no records in it.

Please Note: This Case Collection Variable(Tray) can only store/have Records of Case Object only. This tray cannot hold/store any other type of variables/records or properties. To solve this issue, see the next step below.

Important : Create a Variable of type Record (Object : Case) to create a blank/dummy Case.

In last step we created a Blank Collection Case Variable (Case Tray). Now we need to fill this empty tray (Case Collection Variable) with new/dummy Cases one by one for each Contact in the Loop so that we can use the whole tray or collection variable to insert cases at once. 

Please Note Again: The Case Collection Variable(Case Tray) can only store/have Records of Case Object only. This tray cannot hold/store any other type of variables/records or properties.

So we will create one more Variable of type Record (Object type Case). This is only a Single Variable (not enabled for Multiple Values)

This case variable will work as as dummy Case record for every iteration of the Loop and we will just change its properties/field values (Subject,Origin,Account) in every loop iteration and add into the Tray (Collection Variable). The variable name is "Case Individual Record"


Loop Element: We need to just loop over the Contacts from the Get Element. Loop variable is automatically created after Summer'20 so no need to create it.
Inside Loop, we will have two Assignment Elements.


First Assignment element is to Assign field Values of Subject, Origin and Account Id to the dummy case Single Variable which we had created ({!CaseIndividualRecord). The Contact name is fetched from Loop Variable as we are looping on Contact. Origin is set as Internal and Account ID is available from the Input variable of type Record and object Account which we created in First Step. This Account value is passed from Account Page to Flow.
Second Assignment is to add this dummy Case( with field values assigned from previous step) to the Case Collection Variable ({!CasesToCreate}or Case Tray as we have referred to it here.

Here is a rough (literally) illustration of how it will work actually.

Things to note in this (apart from my bad handwriting and drawing) is that, dummy Case variable's field values are changed in every iteration and that dummy case is added in Case collection (Tray) variable in every iteration.

After Loop ends, for each Contact, we would have added one dummy case into the Case Tray as shown in the pic above.

At Last, using a Create Record Element, we will just insert the case records in the Collection Variable ({!CasesToCreate}) at once.

Checkout Videos below for detailed steps of Flow Creation. 

Please Note: The Screen Element in this Flow has no real purpose. It is just to show the Flow on Account Page and provide a Button to Fire the Flow.

Creating all the Variables needed in Flow


Get Element to Fetch Contacts

Screen, Loop and Create Element

Add the Flow on Record Page and Pass Record Value to Flow + Demo of Our Example : After Saving and Activating the Flow.

And we are done!

Note: Using this approach, we are following best practices to develop a Flow and are just ensuring that Flow won't hit governor limits when data is within accepted limits. We are in no way bypassing any of the Governor limits. To check different transaction limits in a Flow see this :https://help.salesforce.com/articleView?id=flow_considerations_limit_transaction.htm&type=5

Please feel free to reach out to me if this is still confusing or if there is a better way to do it. 

NOTE This article is showing Flow Bulkification while creating Multiple Records in a Salesforce Flow. If you want to see how to Bulk Update in Flows or Mass Update Records in a Flow then checkout this article for better understanding : Mass Update Records in a Flow

Checkout all other Flow related Posts on my Blog here: https://www.accidentalcodersf.com/search/label/Salesforce%20Flow

Do share feedback or comments if you explore more on this feature or if you have any better ideas or scenarios. Thanks for reading. Hope this helps!

In other News, My Blog AccidentalCoderSf.com is featured in the TOP 50 Salesforce Blog List maintained by Feedspot. Checkout the Full List here: https://blog.feedspot.com/salesforce_developer_blogs/ 

Please Subscribe and never miss any Latest Post on this blog!
Enter your email address:


Delivered by FeedBurner

Comments

  1. I love these posts. Thank you so much!!

    ReplyDelete
  2. Hi @Vibhor,

    A quick question for you not sure if you're able to help answer. I am trying to bulk update a set of data via a flow.

    I built a flow on account based on field value input for the shipping state field to update the region field to the appropraite region. The region and states are referenced in custom metadata type. My trigger is a process builder (shipping state != global constant empty string or ischanged(ShippingState) and passing the entire account record.

    The flow works perfectly fine but we noticed that if we insert a batch of data, the flow can't bulkify to update the accounts to the corresponding region. I think I have to somehow bulkify the update by incorpoarting a loop but I haven't been able to on the Get Element from the custom metadata type to save the records into a collection variable.

    Any insights would be helpful! Not sure if this makes any sense here but appreciate your help!

    ReplyDelete
    Replies
    1. Hi, It would be difficult to know the exact cause without seeing the flow but normally flow and process builder are able to handle bulk transactions. In loop you need to assign values for each record.

      Delete
    2. Thank you for your response Vibhor! You're obsoletely correct - PB are able to handle bulk transactions! We were passing the whole record instead of the individual ID and when we pass the record ID instead, the insert was successful.

      Delete
  3. Hi Vibhor, thanks for a great lesson on inserting multiple records. I had a couple questions: I understand that after we loop through all the contacts on an account we need to assign the case values(individual) and then add them to our dummy collection/case tray. You said "add this dummy Case to the Case Collection Variable " but the screenshot shows the Collection Variable being added to the individual variable(basically the other way around). Does it matter what order you select on the assignment screen? Or no because it's addition?

    Why does the Assignment for the collection tray(cases) connect back to the loop? Is that so it can start the whole process over again of iterating through a contact, storing a dummy case, then dumping it in a tray until finished?

    I also see that after the loop ends then we Create our Cases, but why does the create element have to be connected to the screen element?

    ReplyDelete
    Replies
    1. Hi , The case single variableis to be added in case collection and that's what we do by using add operator in assignment element.Therefore I am doing {!casestocreate} add {!caseindividualrecord} which means to collection I am adding the single record. Alos, we need to close the Loop in answer to second question . And lastly no need to connect the create to screen its not mandotory..

      Delete
    2. Thanks for the quick response. It looks like the Loop is closed by the Create Element. Why do we need to attach the second assignment(case collection tray) element to the loop?

      Delete
    3. Hi, inside the loop we need two assignments as I explained in article. So after second assignment it closes the loop. Once loop is done with all the iterations, then it will be going to create element which is not a part of the loop and it runs after last loop iteration. Checkout videos for more clarity. You can also checkout another article for mass update functionality which is quite similar https://www.accidentalcodersf.com/2020/12/flow-bulkification-mass-update-records.html

      Delete
    4. With this approach, will we always have two assignment elements? One to hold the individual values, and one assignment element that holds multiple values and then they close off the loop. Then we add the individual record to the collection tray?

      Delete
  4. Thanks for writing this up. I was struggling to get my head around creating multiple tasks associated to a single case and this got me sorted.

    ReplyDelete
  5. Hello Vibhor ,

    I have the following scenario :

    - Object called " Project " - from which I wanna take data from different fields.
    - I want to find and get only projects with a specific characteristic
    - I want to take projects with a checkbox ticked/unticked.

    After I take the project information I want to create a record from another object called " Project Emails ".
    After I create the "Project Emails " I want to create inside an Object Project Batch records for all the Projects that meet my characteristics.

    I tried to do this but somehow it's not working . What am I doing wrong?

    https://www.screencast.com/t/RuZxpaHzaAo

    ReplyDelete
    Replies
    1. hi, please try to debug from the debug option and see at each step what data is being passed to each element. Looking at the video couldn't think of anything but debug on canvas will be more helpful to analyse the issue

      Delete
  6. Hi Vibhor, Thanks for this explanation. I think I can use it. Currently I'm working on a project to import a csv file that will be converted to records. I found a flow component (Apex) for this conversion. I had to change it because it was based on US format only (comma seperated, comma as thousands separator, point as decimal separator) and I added the possibility to enter the field/thousand/decimal seperator in the flow component and changed the code to handle the csv in the right way. From these records (a little over 300) I have to create as many records in 2 different custom objects, dependant on the value of 1 specific field. If that field is empty, the 300 records must be made in 2 other custum objects. In both cases, the records in the second object must be related to the records in the first custom object.
    In that specific field is filled, then all the records can be created alter they are matched to the case they are related to. In case that specific fiels is empty, there is a time out error because it can not be done within 10 seceonds. If I import a CSV file with only 100 records, it can finish in time. (This is because of triggers on the objects that cause the delay)
    I will try to bulkify it the way you described and hope to create the records without the timeout error. Otherwise I have to think of a way to schedule some batches to complete this with maybe 50 records per batch.
    Kind regards,
    Hijlko

    ReplyDelete
  7. This post was really useful. Thanks for writing and sharing it with us

    ReplyDelete
  8. how many records can I update using a single update records element? how many records can I delete using a single delete records element? how many records can I create using a single create records element?

    ReplyDelete
  9. You have solved all the mysteries of creating/updating records outside of loops for me! Thank you!!
    I have a question though, not sure how to go about it:
    I have a get records element to find "Object X" based on criteria, there are multiple records found, I then want to use a get records element to find related records "Object Y" where a field is equal to those in Object X collection - how do I do this for each record without using the second Get Records in a loop?
    I need to check if there are already records of "Object Y" relating to each of record "Object X" in the collection, if there are no records I can go on to create them, if there are records, I don't want any more to be created.
    Any help on this would be amazing - thank you.

    ReplyDelete
  10. Hi Vibhor,

    I'm new to salesforce and your blogs are very helpful. Thank you!

    I followed all your steps and it works great. But I need to start flow using action button, how would I do that ?


    When adding the flow on the page there is an option to check "Pass all the field value from the record into this flow variable " but when using action button there isn't any place to check, I think this is the reason action button is not working. Could you give me some guidance.

    Thanks,
    Al

    ReplyDelete
  11. Hi Vibhor

    Thanks for this posting, super helpful explanation of the trays, had struggled to find an example online for this scenario and this was perfect - cheers!

    Nic

    ReplyDelete
  12. Excellent explanation, thanks a lot for sharing it!

    ReplyDelete
  13. Thanks a lot for this detailed explanation. Looking forward to more such articles!

    ReplyDelete
  14. Hello Vibhor,

    Thank you so much for the explanation.

    I have a doubt: In your case we are linking the case objects with account Id which we already have, how can we link a case which needed to be created inside loop with a Task which is already created. For this we have to add the case Id in the task 'related to' field but inside the loop the ids of new cases are not yet generated. Can you please help me how to achieve this?

    ReplyDelete
  15. Hi! is there a way that instead of doing the mapping of values through assignment we use an existing action which already has the mapping of the fields? I have a quick action in contatc to create leads from contact and values from contact to lead are mapped. Then I have a flow that is triggered from another action in campaign object and when clicked it should create a lead for all contacts inside the campaign. instead of doing the mapping all over again inside the flow i would like to just use the existing one from quick action

    ReplyDelete
  16. Great blog ! Your writing style is engaging and the way you present your ideas is both articulate and compelling. online cyber security course

    ReplyDelete
  17. Greaatt, finally understood this

    ReplyDelete

Post a Comment

Thanks for your Feedback!

PLATFORM APP BUILDER CERTIFICATION - 78% OFF

POPULAR POSTS

Salesforce Flow Examples : Flow Use Cases and Scenarios

Flows | Use Flows to Bulk Update Records from List View in Salesforce

Flow Bulkification | Mass Update Records from Flows in Salesforce


Never Miss Latest Posts