#RecordTriggered

2023-08-09

One Big Record-Triggered Flow or Multiple?

The question of whether to construct a single, all-encompassing record-triggered flow or to deploy multiple, specialized flows is a recurring topic of discussion amongst Salesforce enthusiasts and experts alike. Further complicating this debate is the consideration of subflows and their role in the architecture of Salesforce automation. Here is a brief disclaimer before we dive deeper: the answer is not one-size-fits-all. I approach this topic with a flexible mindset, understanding that what works in one scenario may not be the best solution in another. My stance on this is far from dogmatic, and I believe there’s merit in examining each use case on its own terms. In this discussion, I won’t suggest that deviating from a prescribed method is erroneous, but rather I aim to shed light on the nuanced decision-making process behind structuring flows effectively.

Now that I got that off my chest, I do have an opinion on the topic

Asking the right question is very important. Is “How many flows should we build per object?” a good question? Generally, I don’t think so. We should ask ourselves: How can I build automation that does not waste system resources, is easily readable, and is easy to maintain?

My priority when I build my flows is that my build should not run unnecessary automation. My most important objective is not to trigger automation when it does not need to run.

In a complex Org, you quickly realize that yields multiple flows per object. When you look at the three tasks that can be performed in one big record-triggered flow, they rarely need to run all in the same scenario.

Now that I told you I heavily use my start element criteria, do I use the formula entry criteria or the line editor with AND/OR operators?

Here is my experience

I often see record-type usage in fairly complex Orgs. I’m not particularly eager to hardcode RecordType Ids in my start element criteria. I prefer to use DeveloperName or Name over Id. And these are only available in the formula editor. So I often end up using the formula entry criteria.

Some of these formulas get very big. But I will give you a simple example:

AND

({!$Record.RecordType.DeveloperName}=”Sales”,

NOT(ISBLANK({!$Record.ContactId})),

   OR(

ISPICKVAL({!$Record.Status},”Scheduled”),

ISPICKVAL({!$Record.Status},”Confirmed”)

      )

    )

Now let’s get to the other popular topic: Subflows

I recently inherited work that another Salesforce partner did. They did a good job but used subflows in many of their flows. I found the outcome very hard to read and understand. The back-and-forth review left me confused and tired.

I only use subflows if I know I will reuse the logic in another flow.

Explore related content:

Emojis ❤️ and Dreamin’ Events 👌

Migrate to Flow Tips

Datatable Component – Salesforce Screen Flow

#Architect #Automation #Opinion #Project #RecordTriggered #Salesforce #SpecializedFlows #Tip

2025-09-09

One Simple Salesforce Flow Hack That Will Change Your Workflow Forever!

What if I told you that the Flow you’ve been building could secretly hold the key to a much bigger impact in the automation world? A world where you don’t rebuild logic over and over… where one Flow powers multiple flows.

Sounds dramatic, right? But once you learn this trick, it will be an invaluable addition to your flow arsenal that will superpower your workflows going forward.

Use case: Create a follow-up task due in seven days for the proposal step when the stage is updated to proposal (do the same on create), if there is no existing open task already with the same subject.

Let’s start by building this use case. Then we will get to the hack part.

Step 1. Build the Original Record-Triggered Flow

We’ll start with something simple: a record-triggered Flow on Opportunity that creates a Task when the Opportunity hits a certain stage. Check whether there is an open task already with the same subject related to the opportunity, before creating another one. If there is an open task already, skip the create.

  • Trigger: Opportunity → when Stage = “Proposal/Quote”
  • Action: Create Task → Assigned to Opportunity Owner
  • Due date: 7 days from the current date
  • WhatId (Related to Id) set as the triggering Opportunity

Straightforward.

But here’s the catch: this logic lives in a record-triggered flow. What if I wanted to leverage the task creation logic for multiple record-triggered flows (including scheduled paths), schedule-triggered flows and possibly for screen flows, as well. In addition, could I leverage the same flow for other object records in addition to opportunities? Good food for thought.

Step 2. Save As an Autolaunched Flow

Here’s where the hack begins.

From the Flow Builder menu, click Save As → choose A New FlowAutolaunched (No Trigger).

Now we have the same logic, but free from the record trigger.

Step 3. Replace $Record With Input Variables

The Autolaunched Flow still references $Record from the Opportunity. That won’t work anymore. Time to swap those out. The references are listed under Errors. The flow cannot be saved until these Errors are fixed.

  • Create Input Variables for everything your logic needs; e.g., recordId (WhatId), OwnerUserIdVar, DelayInDaysVar.

    • Update your Create Task, Get Task elements and the Due Date formula to reference those input variables instead of the $Record.

    Boom. Your Flow is now a Subflow – it can take in data from anywhere and run its magic.

    Step 4. Refactor the Original Record-Triggered Flow

    Time to circle back to the original record-triggered Flow.

    • Open the Flow, Save As a New Version.

    • Delete all the elements. (Yes, all. Feels risky, but trust me.)

    • Add a Subflow element.

    • Select your new Autolaunched Flow.

    • Map the input variables to $Record fields, and provide the delay in days parameter value.

    Now, instead of directly creating the Task, your record-triggered Flow just hands $Record data to the Subflow – which does the real work.

    Here is how the debug runs works.

    Why This Hack Changes Everything

    This one move unlocks a whole new way of thinking about Flows:

    • Reusability – Logic built once, used anywhere.

    • Maintainability – Update the Subflow, and every Flow that calls it stays consistent.

    • Scalability – Build a library of Subflows and assemble them like Lego pieces.

    • Testing Ease – Some flow types are hard to test. Your autolaunched subflow takes in all the necessary parameters in the debug mode, and rolls back or commits the changes based on your preference.

    Suddenly, your automation isn’t a patchwork of disconnected Flows – it’s a modular, scalable system.

    The Secret’s Out

    I call this the “Save As Subflow” hack. It’s hiding in plain sight, but most builders never use it. Once you do, your workflow will never be the same.

    Remember, you can make your subflow logic as flexible as you want. You can add input variables for subject and description. This would make your task creation even more flexible so that it can be used for other objects like Case and Custom objects.

    Try it today – and the next time you find yourself rebuilding logic, remember: you don’t have to. Just save it, strip $Record, add input variables, and let your Subflows do the heavy lifting.

    Explore related content:

    Automate Permissions in Salesforce with User Access Policies

    When Your DMLs Have Criteria Conditions Other Than Id

    Display Product and Price Book Entry Fields in the Same Flow Data Table

    How to Use a Salesforce Action Button to Validate Lookup Fields in Screen Flows

    #Hack #HowTo #RecordTriggered #Salesforce #SalesforceAdmins #SalesforceDevelopers #SalesforceTutorials #Subflow

    The Only Salesforce Subflow Hack You’ll Ever NeedTask Create Record Triggered FlowSave As A New FlowGive Your Flow Label
    2025-03-31

    Can You Start With a Decision Inside Your Record-Triggered Flow?

    When you build a record-triggered Salesforce flow, you may need to use the decision element to differentiate the path your flow takes based on conditions. Before we dive further into best practices, let’s take a look at what the decision element in flow is and what it does.

    Decision Element

    Salesforce Flow Decision Element is a logic component used in Flow Builder to route your flow’s path based on specific conditions. Think of it like an “if/else” or “switch” statement in programming—it lets you control what happens next depending on the data or situation.

    What It Does: The Decision Element evaluates data from the flow (like record fields, variables, or formulas) and then directs the flow down a specific outcome path depending on which conditions are met.

    Key Parts of a Decision Element:

    • Label & API Name: A name for easy reference.
    • Outcome(s): These are the different paths the flow can take. Each outcome has a Label and Condition.
    • Default Outcome – A fallback path if none of the other outcomes match.

    🚨 Use Case 👇🏼

    Let’s say you have a flow that processes a case. You can use a Decision Element to check the case priority: Outcome 1 will send the case to the Escalation Queue, if Case Priority = High. Outcome 2 will send the case to the Standard Queue If Case Priority = Medium or Low. The Default Outcome will log an error, send a notification or do nothing.

    Record-Triggered Flow

    A record-triggered flow is a type of Salesforce Flow that automatically runs when a record is created, updated, or deleted. It’s often used to automate tasks like updating related records or sending notifications.

    Record-Triggered flows are subject to a popular debate: Experts have varying recommendations on how many record-triggered flows are optimal on a given Salesforce object (e.g. Case).

    The best practice recommendation and the anti-pattern definition here will be highly dependent on this approach.

    One Record-Triggered Flow or Many on a Single Object?

    My recommendation is that you can and should have multiple record-triggered flows on a single object, if you can optimize the start conditions to ensure only a small subset of the record-triggered automation logic is executed for a particular record. If you try to combine all the logic into a single flow, you will not be able to tighten your start element conditions effectively, instead you will resort to using decisions to differentiate paths inside the flow.

    Why Starting Your Record-Triggered Flow Can Be an Anti-pattern?

    Considering all these factors listed above, using a decision that follows your record-triggered flow start element most likely points to an inefficient design: You use decision outcomes to differentiate business logic, when you could separate these paths into multiple record-triggered flows and add these conditions to the start element.

    Let me explain.

    🚨 Use case 👇🏼

    You have three record types for the case object representing Hardware, Software and Other. You have a fairly sophisticated record-triggered flow to process new Cases. For the Other record type your flow does not do anything.

    If the solution in this case is to use a decision element inside your flow connected to the start element to check the record type, then you should consider separating this record-triggered flow into three different flows.

    And if some of the business logic repeats for more than one record type, you should consider leveraging subflows.

    Why Is This Design More Efficient?

    There is a system overhead associated with starting a flow execution. If you execute your flow and evaluate conditions in the decision element, you already used cloud resources. If you can stop your flow from executing, you won’t use any resources. Start element conditions stop the flow from executing.

    Can you achieve this just by tightening your start element conditions and excluding the Other record type? Sure, you can. Is the use case always this straightforward. Not, really. For more complex use cases, it may make sense for you to split your flow into multiple record-triggered flows.

    Conclusion

    While using a decision right after your start element may make sense in certain situations, it is a potential anti-pattern you should watch for. If this is a flow somebody else built, or you built ages ago, seeing this pattern should prompt you to inspect and reevaluate the design in this flow.

    Leveraging multiple record-triggered flows on a single object with the support of flow trigger explorer and the execution order setting can be a very good idea in these situations. If your business logic repeats in your triggered automation, you should consider leveraging subflows for easier maintenance.

    This post is part of our Best Practices series! Click HERE to see the rest of the posts.

    Explore related content:

    A Comparative Look at Flow Decision Elements in Salesforce

    How to Use the Action Button Component in Screen Flow

    Start Autolaunched Flow Approvals From A Button

    Error Screen Message Design in Screen Flows

    #Automation #RecordTriggered #Salesforce #SalesforceAdmins #SalesforceDevelopers #SalesforceTutorials
    Decision element record-triggered flow salesforceDecision element record-triggered flow salesforce
    2024-12-02

    Salesforce Flow Best Practices

    Best practices in flow revolve around principles that enhance low-code quality, maintainability, and collaboration. Key practices include, but are not limited to, building clear and concise automation with meaningful resource names to improve readability and consistently adhering to standards for uniformity.

    Overall, following best practices leads to more efficient and effective automation.

    Antipatterns in flow refer to common practices or solutions that may seem beneficial but ultimately lead to poor software design, increased complexity, or maintenance challenges. They are the opposite of best practices and often arise from attempts to solve problems without fully understanding the implications. Recognizing and avoiding antipatterns is crucial for creating clean, efficient, and maintainable code.

    While reviewing legacy flow automation is very different from reading and reviewing code, the visual builder flow canvas presents opportunities to spot antipatterns easily.

    I gathered the antipatterns I have seen throughout the years and created a slide-set for a comprehensive list. This list is not meant to be the definitive list. I hope it will start fruitful discussions around the topic, which may yield better flow automation quality in the ecosystem.

    This post will start a best-practice blog post series. Each item on the list will receive a comprehensive post, and I will link it to this master post upon completion.

    Without further ado, let’s dive into the list:

    1. Can You After-Save When You Can Before-Save? Consider performing the same record updates in before-save flows.
    2. Can You Use DML or SOQL Inside the Loop? While there are situations where you may need to break the rule, DMLs and SOQLs (Create, Update, Delete, and Get) should be placed outside the loop.
    3. Is Your Salesforce Flow Too Big? Consider a modular approach and leverage subflows for an easily maintainable structure when your flow becomes too big.
    4. Can You Start With a Loop Inside Your Schedule-Triggered Flow? When you loop immediately after a start element with an object associated, you will loop for every record the flow launches on. This design is not often intended and will potentially generate faults.
    5. Can You Loop Inside a Loop? While this may be necessary in certain situations, it is often a sign of a weak design. Loops inside loops will cause a high number of iterations, hurting performance and usually yielding faults.
    6. Can You Start With a Decision Inside Your Record-Triggered Flow? Starting your record-triggered flow with a decision creates two or more distinct paths inside your automation, which you can split into multiple flows with tighter start element conditions. The latter often is the better-performing design.
    7. Formula Resources in Criteria Conditions—Yes or No? Instead of inserting formula resources in criteria for decisions and updates, you should consider building multi-line conditions combined with AND and OR operators.
    8. When Your DMLs Have Criteria Conditions Other Than Id. Updates that include conditions beyond specifying the Id of the record consume one SOQL and one DML against your execution governor limits; make sure you check and control your governor limit usage.
    9. Should You Leave Unused Input and Output Variables? Mark your variables as available for input and output only when necessary for security reasons.
    10. Is Your System Context Usage Necessary? Heavy-handed use of system context without sharing can cause unwanted changes in your database. This increases the harm caused by a potential attacker running the flow.
    11. Should You Use Fault Paths? Your DMLs, SOQLs, and Actions need a fault path to ensure the whole transaction does not fail. Fault paths can offer custom messages and alternative routes, preventing complex system fault messages from being displayed to the user.
    12. Should You Use Roll Back Records In Screen Flows? Roll Back Record element provides a way for you to roll back the recent DMLs,  and ensures that half-baked record updates don’t persist in the database.
    13. Is Hardcoding Ids a Good Idea? Hardcoded Ids are potential points of failure especially when deploying flows between unconnected environments like scratch orgs.
    14. What Is The Best Way Of Checking Record Types in Record-Triggered Flows? You can check for record type developer name or name in your record-triggered flow start element without needing a get element inside your flow.
    15. Should You Hardcode Business Logic In Your Flow? If there is frequently changing business logic in your flow, the preferable approach is to build this on a table outside your flow and have SMEs update the reference table.
    16. Are Your HTTP Callouts and Outbound Messages on an Async Path? Salesforce requires integration messaging to execute on an async path. In schedule-triggered flows, the wait element provides a similar function.
    17. Is Your Flow Comparing and Processing Collections? When you go down into the related records, find junction objects, and perform enhanced operations with collections, you may be better off leveraging Apex.
    18. Are Your Email Actions on an Async Path? Perform email actions and create trivial object records for internal follow-up on an async path. This ensures that the main part of the execution does not slow down or stop due to performance or error reasons.
    19. Other Miscellaneous Items: Testing, naming, comments, documentation, null check etc.

    Let’s start with the obvious: Build in the sandbox, debug, and test your flows very well. Create good documentation for your flows, add comments and descriptions, and follow naming conventions.

    Here are the slides I created for this topic:

    View and download Salesforce Flow Antipatterns and Best Practices here.

    I presented these items at London’s Calling, Apex Hours, and Trailblazer User Group Meetings.

    Everyone is welcome to comment on the blog posts, and I will read them and respond to them.

    Explore related content:

    6 Things You Can Do With The Transform Element

    Top 9 Salesforce Winter 25 Flow Features

    #AfterSave #Antipatterns #BeforeSave #Element #HowTo #Loop #Record #RecordTriggered #Update

    This is the Flow Best Practices blog image

    Client Info

    Server: https://mastodon.social
    Version: 2025.07
    Repository: https://github.com/cyevgeniy/lmst