I'm building a Flow to update sequential values on records.

  • Each record (CampaignMember within a Campaign of specific record type) has a numerical "rank" value that can be set manually by a user.
  • When a value is changed on one record the Flow updates all the records that need to be changed in order to keep the rankings sequential and prevent duplicates.

So for example, if I set a record's rank to 7 and there are already records with ranks 7, 8, and 9, the existing records should all be incremented by one.

The Flow works, however, since each record is updated the Flow gets triggered again by each subsequent record that is updated. I could modify the Flow to only touch one record at a time but that would be really inefficient.

Currently I load up the other CampaignMember records that need to be updated, loop through them incrementing, or decrementing, their rank and put them into a variable collection that is saved at the end.

What would be nice is if I could only run the Flow when I can detect that the record was not updated by a Flow. Is there a way I can do this so that I can make the updates in bulk?

  • 1
    Idea (I've not tried this): Stamp each update with $Api.Session_Id in a field called Rerank_Session_Id__cand when you recurse, if the record's stamp matches $Api.Session_Id, you know you don't need to do any further action in that Flow Interview
    – cropredy
    Nov 30, 2021 at 2:08
  • Interesting idea. I took a look at this but it appears the Session_Id stays the same for a long time. I might look at the time when it was last updated and if the record was updated within the last few seconds then I'll ignore it. The user will likely make multiple changes within a 10 minute time period so having the Session_Id being the same throughout that duration won't work.
    – kd7iwp
    Nov 30, 2021 at 17:43
  • Ah, right. The sessionId lasts as long as user is logged in. You could use a static variable set of ids in an apex invocable to act as a semaphore as to whether you have visited that id prior to reranking
    – cropredy
    Nov 30, 2021 at 18:41
  • It appears I am having success by having an initial decision in the Flow that looks at the Last Modified date on a campaign member record and if it was modified in the last 5 seconds it immediately stops execution.
    – kd7iwp
    Nov 30, 2021 at 19:13

1 Answer 1


What you are looking for is some indication of transaction state to control recursion

In an Apex trigger, this would be done with static sete of IDs that you have already visited. But, since you are using Flow, perhaps the following is a robust solution:

Step 1

Create an invocable Apex class that accepts a list of Ids and returns a list of Booleans

static Set<Id> visitedIds = new Set<Id>();
public static List<List<Boolean>> isVisited(List<List<Id>> interviewsIds) {
   List<List<Boolean>> results = new List<List<Boolean>>();
   for (List<Id> interviewIds: interviewsIds) {
      List<Boolean> interviewResults = new List<Boolean>();
      for (Id id: interviewIds){
         if (visitedIds.contains(id)) {
          else {
    return results;

Step 2

Have your Flow use an Apex Action and pass the id collection of records you are considering reranking.

The Apex action will return a collection variable of true/falses in the same order as the id collection and you can loop through those to decide whether to rerank


Initial pass of a flow interview is for Id 7 and you are going to rerank 8,9,10

You pass to the Apex action the Ids for 7-8-9-10 and get back all falses. This tells you can rerank with an Update element

When records 8-9-10 get updated and enter the flow again (same transaction), the flow will invoke the Apex Action again but this time it returns a collection of all falses - so the Flow Interview does no Update and essentially stops


This solution avoids the timestamp solution you proposed in your comment which would work "most of the time" but edge cases could compromise the 5 minute rule at some point in the future, perhaps long after you are gone from the scene

Note also that because there could be many records running flow interviews, the invocable apex has to be bulkified, hence the List<List> argument

You must log in to answer this question.

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