7

I have a process built with a Process Builder. It fires on contact update/create.

Under certain conditions that process launches a Flow. Flow accepts two Parameters - ContactId and AccountId.

If I do mass update/insert of the contacts and flow is launched through the process, the flow is automatically bulkified disregarding the fact that flow itself accepts a single value of each Id. So, if I upload 100 contacts the flow will query info about the related accounts in one query.

Is there a way to implement the same behavior while launching the Flow from the apex?

I was trying something like the code below but it just launched flow 4 times and even put it into the same apex transaction.

Map<String, String> allParams = new Map<String, String>();
allParams.put('003XXXXXXXXXXX1', '001XXXXXXXXXXX1');
allParams.put('003XXXXXXXXXXX2', '001XXXXXXXXXXX2');
allParams.put('003XXXXXXXXXXX3', '001XXXXXXXXXXX3');
allParams.put('003XXXXXXXXXXX4', '001XXXXXXXXXXX4');

for(String contactId : allParams.keySet()){
    Map<String, Object> params = new Map<String, Object>();
    params.put('ContactId', contactId);
    params.put('AccountId', allParams.get(contactId));
    Flow.Interview myFlow = Flow.Interview.createInterview('GreatestFlowOfAllTimes', params));
    myFlow.start();
}

I also tried to pass list of parameters instead of single values like:

Map<String, Object> params = new Map<String, Object>();
            params.put('ContactId', new List<Id>{003XXXXXXXXXXX1, 003XXXXXXXXXXX2, 003XXXXXXXXXXX3, 003XXXXXXXXXXX4});
            params.put('AccountId', new List<Id>{001XXXXXXXXXXX1, 001XXXXXXXXXXX2, 001XXXXXXXXXXX3, 001XXXXXXXXXXX4});
            Flow.Interview myFlow = Flow.Interview.createInterview('GreatestFlowOfAllTimes', params));
            myFlow.start();

And it doesn't work as well.

Documentation does not provide info about bulkification at all.

Maybe I'm missing something. Please advise.

2 Answers 2

3

Calling start() on a flow interview object within a loop is NOT bulkified - even if all the flow interview objects are for the same flow.

This has to be because the start() method executes synchronously

So, when does this matter?

  • If the flow you are calling does
    • Get Record (SOQL - subject to 101 per transaction (sync)) or
    • any of the DML elements - Create/Update/delete - subject to total transaction DML limits

There's a reason why the Apex Flow.Interview documentation is slanted towards apex controller use cases - where you are likely to be operating on a single record and calling start() only once.

Now, can you work around this? Yes - but at a cost

If you design the called Flow to accept as input a collection of objects and to return a collection of results, then you only need the Apex code to marshal all the inputs into a single collection, invoke start() once, and then unmarshal the results once the Flow has returned.

You can see a trivial example of this in the Record Updater from the AndyInTheCloud Calling Flow From Apex blog post

The cost? Depending on your use case, if the flow does any database interaction, since the single Flow Interview is going to iterate over a collection of inputs, it has to build collections of variables in loops so a single SOQL or DML is performed per Flow Interview. You might as well code up the logic in Apex rather than try to replicate the conciseness of Apex control logic in Flow Loop, Assignment, and Decision elements.

Other references

1

Here is some documentation about flow bulkifkcation.

https://help.salesforce.com/articleView?id=flow_concepts_bulkification.htm&type=5

My understanding is that Salesforce will "intelligently" bulkify the query to help stay within limits, but each interview should still run independently after the query.

That said it's always felt a bit squishy to me and I am reluctant to use pb/flow in cases that will need bulkification.

5
  • This article explains how to manage flow itself. But I am looking for a way to reproduce the flow behavior when launching from apex. It seems extremely weird that we can't launch the flow for apex in the same way it is launched from PB so I assume I just missing something. Jul 29, 2019 at 10:39
  • 1
    I see now, agree it ought to be feasible. Wild guess, but what if you first add all interviews to a list of flow interviews, and then iterate over the list to call the start method. Doubt it would change anything. Good question, hope someone can elaborate.
    – gorav
    Jul 29, 2019 at 12:30
  • I've tried it as well. It work the same way Jul 29, 2019 at 13:01
  • Any Update on this? Apr 18, 2020 at 22:19
  • 3
    I had the same thought to iterate over the list of flows can start sequentially to see if the system is smart enough to bulkify them... It's not. We need a method like Flow.Interview.start(listOfInterviews);
    – NSjonas
    May 13, 2020 at 19:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.