1

If I have an invocable method that is bulkified to handle multiple records updated in a single transaction, what is the most efficient way to write the Flow that calls it?

My initial Flow design lets the Flow's record-by-record interview send each single updated record that enters the Flow to the invocable method (as List< sObject >). My dev instincts tell me to send all the updated records to the invocable as a collection (List<List< sObject >>) just like Trigger.new would do, but is that necessary? Wouldn't Flow still run a distinct interview for each record and end up sending the same collection of all updated records repeatedly?

It's working as-is but I can see it using a lot of resources for each additional record I add, so I'm hoping that there's a Flow bulkification design I can apply.

3 Answers 3

1

If you have an invocable method that runs with certain input, it should be coded as if you are passing the items from a transaction context into it. That is, if your flow runs on an object creation or update, it is the equivalent of creating an Apex method that handles the context of that transaction - the list of records or inputs from the flow.

So, if you have a method with a signature of (List<SObject> records), it means that your invocable method will be invoked once for a batch of records in a transaction context. I'm saying this because even for triggers the records are split into batches of 200 records. In this example, if you are performing some DML in an object that triggers a flow that calls this Apex action, if you define that records input variable in the Flow Builder UI as the $Record variable from the flow, it means that when your flow runs, it will run that method for all the records of that object in that transaction.

As an example: if you have a flow that runs this Apex action whenever an Account is created, it means that if you create five Account records that list passed onto your method will contain the five Account records.

The same principle applies to signatures using custom Apex subclasses. It is common to have an action defined as a class and then have a subclass to represent its inputs, like so:

public class MyAction {
    public static void run(List<Input> inputs) {
        // ... do something with inputs
    }

    public class Input {
        @InvocableVariable(label='Name')
        public String name;
    }
}

In this scenario, imagine you are passing the $Record.Name (the Account's name) as the value for the action's input in the flow. If you have five Account records in the transaction, then the action will receive a list of all of your records' Name values in that name attribute of the custom element. Subclasses like this are common for situations where you need to process multiple parameters.

1
  • I had to prove to myself that passing just the $Record variable from the Flow to the Apex Action was the equivalent of passing trigger.new so I added a trigger and compared my bulk test method results with either the Flow or the Trigger active. Both generated the same number of queries, DMLs, etc in the cumulative usage. It felt counter-intuitive and is the simplest Flow (just Start + Apex Action) I've written but it works beautifully. Commented Jul 31, 2023 at 21:59
0

If the invocable is coded as

 ...(List<Request> requests) { ..}

then each Flow Interview should pass a singleton variable as a request

If the invocable is coded as

 ...(List<List<Request>> requestCollections) { ..}

then each Flow Interview should pass a collection variable as a request

It all depends on your application logic. If a single Flow Interview is working with a collection variable and that needs to be delegated to the invocable, use the List<List>> requestCollections approach. Otherwise, and for most use cases, the Flow Interview is dealing with a single "record" and then the interview would pass that single "record" to the invocable using a signature of List<Request> requests

  • Flow Interview 0's data corresponds to the 0th element in the invocable's array
  • Flow Interview 1's data corresponds to the 1st element in the invocable's array
  • ...
0

Salesforce bulkify your transactions if you are using Apex action element . See the screenshot below. enter image description here

If you have an invocable action that takes List as parameters just passe the record variable to your apex action. In the apex actions salesforce wait for all the record in the transaction to come then it passes it as a list to your invocable actions.

Ex. Your are creating 100 case record in bulk. In the transaction , your flow will process the record , one by one and group it near the element that can be bulkified , in your case the apex action, then it passes it to the class.

If you want to know more about cross-batch bulkification . see the documentation here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .