Flow

Master Salesforce Flow in 90 Days: My Learning Journey

By Mariel Domingo

If you’re new to Salesforce, this could very well be the first time you dabble in automation within the platform. But if you’re not a Salesforce newbie and have been comfortable with the OG automation tools like Process Builder and Workflow Rules (like me!), then your first rodeo with Flow Builder can feel both exciting and intimidating. I know, I’ve been there, and the idea of switching to something more complex might feel like a steep climb.

But here’s the thing: Flow doesn’t just replace those legacy automation tools we’ve grown comfortable with – it’s a significant upgrade. With Flow, you can do everything you used to do in Workflow Rules and Process Builder – like sending emails, updating fields, or assigning tasks. But it doesn’t stop there. Flow lets you go even further with building step-by-step screens to guide users, create branching logic, and connect across multiple objects. Despite these sounding pretty complicated to implement, the best part is you can do it all without writing a single line of code.

My Flow Learning Journey (So Far)

I’ll be honest (if it isn’t obvious yet) – I didn’t “fall in love” with Flow immediately. But with news of the Workflow Rules and Process Builder retirement, along with pretty aggressive developments to Flow, I knew I had to learn it. Flow has become the standard for declarative automation, so to build solutions that scale and are future-proof, Flow is the way to go.

You might already be learning through Trailhead or have followed our Flow content and tutorials over the years. This isn’t another one of those. This will be a personal learning experience shared with you. Kind of like a diary. 

Learn alongside me and let me take you on this flow journey. Each week, I’ll share what to learn and what you need to know – in plain terms. You can use it as a rough outline to design your own learning plan, or to find resources that support your self-study. I’ll include examples that made things click for me, things I wish I knew earlier, or any mishaps or surprises along the way.

This article will be updated every week throughout the 90-day journey, so feel free to bookmark it and check back for the latest post!

Week 1: So… What Is Salesforce Flow?

Week 1: So… What Is Salesforce Flow?


Flow is a powerful automation tool that lets you:

  • Automatically update, create, or delete records.
  • Send emails or notifications.
  • Assign tasks or trigger approvals.
  • Collect information from users through screen flows.
  • Perform actions across objects, even if they aren’t directly related.
  • …and more!

I know not everyone will remember biology class, but if you think of Salesforce as the body and brain of your business, Flow is like the central nervous system. It connects everything and tells each part what to do and when – responsible for coordinating complex, high-impact automations that touch multiple parts of your org.

Then you’ve got other automation tools, like Workflow Rules and Process Builder (retired but still lingering), and even things like formula fields or validation rules. These are more like the peripheral nervous system, like the reflexes or individual nerve endings. Still important, can work together with Flows as well, but are more limited and don’t offer the same level of control or flexibility.

In short, Flow is where your business logic really comes to life. It’s how your ideas, like “if this, then that” come to life behind the scenes. It’s insanely powerful and can make things happen in your org without needing to lift a finger each time. Imagine collecting info directly from users, performing logic across multiple objects (even if they’re not related), and so much more.

Probably the most basic skill needed here is just to understand logic. And when you finally get the hang of it, recognizing patterns and solutions everywhere will be second nature to you. Problems that once seemed impossible or required tons of custom code suddenly have elegant answers. You’ll catch yourself thinking, “Wait, I can automate that”, or “I bet Flow could fix this”. It shifts how you look at problems, not just in Salesforce, but in how teams work, how data moves, and how things could be better.

Sounds good, right?

Businesses have unique requirements and processes, and so there are different types of Flows that can cater to your every need (yes, they can look intimidating at first).

Week 2: Understanding Flow Types (and When to Use Them)

Week 2: Understanding Flow Types (and When to Use Them)


Alright, we’ve covered *what* Flow is. Now it’s time to talk about the different types of Flows, because, yes, there’s more than one, and knowing when to use each type is one of the most important things to learn early on.

The key here is not to memorize every detail, but to understand the categories and get familiar with the pain points they’re designed to solve. Here’s a quick rundown of the five main Flow types.

1. Screen Flow


This is my personal favorite, mainly because it does something neither Process Builder (PB) nor Workflow Rules (WF) could ever do. It’s the only Flow type that actually shows up on the screen and interacts directly with users.

Sample screen for internal employees requesting reimbursement.


You know how, sometimes, you want to guide someone through a process, step by step, without overwhelming them with a bunch of fields or instructions on a page? That’s where Screen Flows take the stage (or screen, pun intended). Think of them like guided forms or mini-wizards that collect input, show or hide fields based on answers, and help users complete a process with confidence.


“Well, why can’t we just rely on the record’s visible fields, field-level security, record types, and validation rules to handle visibility or data quality?”, you might ask. “Don’t those already make sure the right things get filled out?”


Fair question – but here’s the thing: relying solely on the record page can leave too much room for error. Users might skip important fields, enter incorrect values or formats, or miss critical context. Sure, required fields and validation rules help, but they’re blunt tools. They kick in after the user tries to save, displaying an error and forcing them to go back and correct the issue. Wouldn’t it be better if users just got it right the first time?


Screen Flows make that possible by guiding users through the entire process from the very beginning. Instead of correcting mistakes after the fact, you’re preventing them from happening at all.


Some examples of when to use Screen Flows are

  • Onboarding new customers
  • Logging support cases
  • Guiding internal teams through complex processes
  • Creating a guided product return or exchange request
  • Creating an internal reimbursement request form (check out this guide on how to let users upload multiple files in Screen Flows…perfect for attaching receipts!)

And if you’re looking to take your flows up a notch, consider using progress indicators to make long forms more user-friendly or explore these handy components that can make your screen flows look better and work smarter – no custom development required.


So you see, screen flows are interactive and customizable, ultimately enhancing the user experience. Once you build your first one, it’s easy to see why this Flow type opens up so many possibilities.

2. Record-Triggered Flow


If Screen Flows are all about user interaction, Record-Triggered Flows are all about *behind-the-scenes* automation. These Flows don’t wait for someone to click a button, as they can fire automatically when a record is created, updated, or deleted.

See how changing the record’s amount above changed reassigned it to a different queue.


Record-Triggered Flows are considered your silent workers, as they keep your org running in the background, handling routine actions. You set the conditions, tell the Flow what to do, and the next time there’s a record that matches those conditions, automation happens instantly.


If you’re a seasoned admin who’s been using PB and WF in the past, this is where most of that logic now belongs. If you’re updating a related record, sending a notification, or setting a field value based on conditions, Record-Triggered Flows can do all of that and more.


But why switch, really? Because PB and WF are on their way out! No really, and even if they weren’t, Record-Triggered Flows give you way more flexibility.


You can build logic that runs before or after the record is saved (yep, kind of like Apex triggers), perform cross-object updates, loop through related records, and even call subflows. You’re no longer restricted to just a handful of basic actions (like in Workflow Rules) or a mile-long chain of criteria nodes (like in Process Builder).


If you’re unsure whether your use case calls for a before-save or after-save Flow, this guide can help you figure it out.


Here are some specific examples of when to use Record-Triggered Flows:

  • Automatically create a Task when a high-priority case is created.
  • Update the Opportunity Stage when a related Quote is marked as Approved.
  • Recalculate a custom field whenever a related child record changes.
  • Assign a custom object to the appropriate queue depending on a field’s value.


Once you start building these, it’s hard to go back. It feels like magic: a record changes, and everything else responds instantly with no extra clicks. So, if your goal is to build powerful, set-it-and-forget-it (wait no, don’t actually forget it, but do make clear names and descriptions) automations, Record-Triggered Flows are your new best friend.


They’re fast, reliable, and obviously a huge step up from the automations of the past. And if you’re wondering what pitfalls to avoid as you start, this article gives an overview of the kind of things you’ll wish you’d known sooner.

3. Scheduled-Triggered Flow


If Record-Triggered Flows are your silent workers, then Schedule-Triggered Flows can be considered your planners: quietly taking care of routine tasks like clockwork. The trigger isn’t a change in data like in the previous one, but simply the passage of time.


These Flows are perfect when you want something to happen on a schedule, like every night, for example, or maybe at midnight or on the first day of each month. Due to their time-driven nature, they’re perfect for sending reminders, updating stale records, or even checking for missing data. Whatever it is, just set the criteria and timing, map out what it’s supposed to do, then Salesforce handles the rest.


As for use cases? There are plenty. Check these out for specific examples:

  • Every Monday, check for open Opportunities with no upcoming tasks and send reminders to owners.
  • On the first of each month, update “Customer_Since__c” dates for Accounts created in the last 30 days.
  • Every night, find inactive Cases and update their status to “Archived”.
  • Every Saturday, deactivate active sales team members who have not logged into Salesforce in over 60 days.


One of the best parts about Schedule-Triggered Flows is that they can run for a batch of records that satisfy your criteria, processing that group of records all at once, which is a huge win for efficiency.


So if you have a task that’s routine, time-based, and doesn’t need a user to kick it off, Schedule-Triggered Flows are exactly what you’re looking for. Set it, let it run, and check in now and then under Setup > Scheduled Jobs to make sure everything’s still running smoothly.

4. Autolaunched Flow


Okay, confession time: when I first heard the term Autolaunched Flow, I thought they just… ran on their own. No trigger, no button, just magically launched somehow. I mean, auto-launched, right? But as I eventually realized (and maybe you have too), it’s not quite that simple.

Source: r/salesforce on Reddit


In Flow-speak, “autolaunched” (with a lowercase a) is an umbrella term for any flow that runs without screens or user interaction. That includes: Record-Triggered Flows and Schedule-Triggered Flows, which we both discussed earlier.


The Autolaunched Flow (No Trigger) and with an uppercase A starts because something else calls it (like another Flow, Apex, or a button for example). The “No Trigger” part just means the flow doesn’t decide on its own when to start; rather, it’s waiting for an outside nudge.


Here are some examples of when you might use an Autolaunched Flow:

  • A button on a record page launches a Flow that performs backend tasks (like mass updates for example)
  • An Apex trigger invokes a Flow to automate part of a custom process
  • Another Flow hands off part of its logic to a separate Autolaunched Flow
  • A Process identifies a condition and calls a Flow to update related records


The third example is great for breaking complex logic into reusable chunks. Instead of repeating the same steps across multiple Flows or automations, you can create one Autolaunched Flow and call it wherever it’s needed. One example is in this situation, where a reusable Flow handles fault paths so you don’t have to rebuild them manually each time. They’re quiet, efficient, and ready when you are.

5. Platform Event-Triggered Flow


Ah, another type of autolaunched flow! You can think of this type as a listener on standby, waiting for a signal to act. The go-signal is a Platform Event that, when published, is picked up by the flow and responds instantly. If you’re unsure of what platform events are and how they work, make sure to check this article out.


Usually, this type of flow is for the more advanced users, as they listen to platform events, which are a way for different parts of the system to talk to each other asynchronously. So, unless you’re dealing with integrations or complex business processes, you might not touch this Flow type for a while. It’s good to know, though, that it’s usually built to respond to events as they happen, so that makes it ideal for near-real-time updates and integrations.


Use it when:

  • You’re working with integrations or system-to-system communication.
  • You want to respond to something that happens outside the regular record lifecycle.

Flow Types at a Glance


We’ve walked through each type one by one, so here’s your side-by-side cheat sheet for when you just need the facts, and a final column to help you remember their “vibe” at a glance.

Bonus: A Quick Look at Orchestrations


Think of an orchestration like a conductor leading an orchestra. The orchestra brings together different people and instruments, and the conductor leads them to create a harmonious performance. In Salesforce, orchestrations coordinate complex business processes by managing multiple flows and human tasks in a well-structured sequence.


Yes, it’s kind of like simply calling one flow from another, but the nice thing about orchestrations is that they offer enhanced visibility, plus the capability to add steps and stages, making them perfect for use cases that involve multiple users or departments.


Steps are the building blocks of an orchestration. A background step can call for an existing active Autolaunched flow, and an interactive step can call a screen flow. These steps can assign a user to that flow. You can dictate more in a step, like what record page the flow should appear on, or whether the user should get an email notification.


Stages are groups of steps. The steps in a stage are executed in the sequence they are in, or in parallel, depending on your business need. These stages can be separated by decision elements to allow for more complex logic.


Simply put, if you need to combine automation and collaboration across teams, orchestration is the key.


While the five main Flow types come included with your org, orchestrations (except for Flow Approvals) are not entirely free. If you do decide to build an orchestration, keep in mind that all orgs receive 600 orchestration runs per year at no charge. These runs reset every 12 months back to 600 regardless of how many were used in the previous year.


You don’t have to memorize anything, but I hope this guide gives you a better idea of how to recognize what’s possible with different types of flow. Nailing the right Flow type helps you automate smarter, not harder. And if you’re ever unsure what type of Flow to create, just head to Setup > Flows > New Flow, and Salesforce actually has a nice visual picker to guide you.

Week 3: Flow Builder UI and Overview

Week 3: Flow Builder UI and Overview


Last week, we walked through the different Flow types and how to decide which one fits your use case. Now, we’re finally ready and jumping into Flow Builder itself: aka, the canvas where all your automation ideas start coming to life.

If this is your first time opening Flow Builder, it may feel overwhelming. But don’t worry, it’s mostly just getting familiar with where everything is, so you know where to click.

A Quick Tour of the Builder


When you navigate to Flows from Setup (or Shortcuts > Flows from Salesforce Inspector Reloaded, which you should definitely check out if you haven’t yet!), it takes you to a list view of all the Flows in your org. Click “New Flow” on the upper right to start building.


Salesforce first asks you what type of Flow you want to create. This is where what we learned last week comes in handy; your choice determines what kind of logic you’ll be able to build and what elements will be available to you. For example, you won’t find Screen as an element to add while building if you chose Record-triggered Flow in the beginning.


Once you make your pick, you’ll land on the builder with just a Start and End node on the screen. This is true for Auto-layout mode, but in Freeform, you’ll just have a Start node.


Let’s break it down:


On the upper left below the back arrow, you’ve got your Toolbox. This is where you manage the building blocks used in your Flow, such as elements (screens, decisions, actions, etc.) and resources (variables, formulas, text templates). It has a handy search bar where you can find the specific elements you need, which is extremely useful, especially for complex flows. So make sure you’re labeling everything right! You can also create new resources from here.


The center canvas is where your Flow is visualized. You can add elements by clicking the plus sign between your start and end node, and every other plus sign that appears between your building blocks as you go (assuming you’re still in Auto-Layout mode). Every element added becomes a part of your process.


The space on the right is reserved for the Settings panel, where any element’s configuration appears as soon as you click on it from the canvas. You can view and edit the element’s configuration from there.

Clicking the Decision element opens its configuration for viewing or editing outcomes on the right side


Since we’re working in Auto-Layout mode, building is as easy as clicking the plus signs as you go. What’s great about this is you already have a clean and organized view of your flow from the start. Even if you end up using multiple decision elements resulting in a lot of branches, they stay well laid out and evenly spaced.


You can drag the canvas and use the “+” or “–” buttons on the lower left to navigate and zoom in or out, making it easy to work with larger and more complex flows in Auto-Layout.


“How about in Free-Form mode?”, you might ask. Well, there are slight differences between building in Free-Form vs. Auto-Layout:

  • The elements in Free-form can be dragged around individually.
  • There are no restrictions on how nodes can be connected in Free-form. Connections and fault paths between elements can be made simply by dragging from one element to the other.

  • The Toolbox has an Elements tab in Free-form, where you can simply drag your chosen element onto the canvas and configure it before attaching it to your flow.

  • Duplicating elements in Free-form is as easy as clicking the Copy button (the one with two overlapping rectangles) while your element is selected. In Auto-Layout, it’s more like copying and pasting: click the “Select Elements” button, select your elements, and then click the Copy button to copy. They’ll be added to your clipboard, where you can just paste them the next time you add another element to your flow. It might seem like a small difference, but knowing how to do it on both modes really helps when you’re dealing with repeating logic.


Another feature I found handy is how Auto-Layout handles subflows. Just click the three-dot icon on the right side of your subflow element and select Open Referenced Flow, and it’ll open the referenced flow in a new browser tab. Unfortunately, Free-Form doesn’t offer the same shortcut.


Though Auto-Layout is my personal favorite, users are usually pretty torn between the two. I even know someone who likes switching multiple times between both modes mid-build! It often boils down to your preferences and which one you get used to.

Source: r/salesforce on Reddit


Another notable section of Flow Builder is the errors panel, which you can access by clicking the button with the circle icon and a diagonal line through it (kind of like a simpler “no entry” sign). This opens a sidebar of errors and warnings, which is great for seeing what needs fixing.


And speaking of fixes…yes, you can undo recent changes with a quick Ctrl+Z! Flow Builder supports a handful of handy keyboard shortcuts like this, so you can work faster without constantly reaching for your mouse. Click the question mark on the upper right and select Keyboard Help to bring up a list of Flow Builder keyboard shortcuts.


The gear icon beside your error panel icon brings up the current flow version’s properties, where you can find the Flow Label, Flow API Name, and Description. Clicking on Advanced will also present what type of flow you’re working on (in case you forget or if you’re on a team dealing with another person’s work).


Once your flow is built, you’ve got a few important buttons to know:

  • Run gives you a quick way to test the latest saved version of the flow by simulating its execution in a live environment. It’s perfect for quick checks to see whether running your flow triggers any errors.
  • Debug lets you step through the flow and see exactly what’s happening at each stage. It’s like Run, but offers more detailed information about your flow’s execution path. It even gives you the option to test your flow in different ways. For example, you can skip the start condition requirements so the flow runs even if the start criteria aren’t actually met, run the flow as another user to see how it behaves under different permissions based on user, or test in rollback mode. These options make debugging both flexible and safe, so you can experiment without fear of breaking anything important.
  • Save as New Version keeps the existing version intact while making your latest version an updated copy, so you can make changes without affecting the active flow.
  • Save stores your progress! It’s best to do this often if you don’t want to lose your progress at unexpected times!
  • Activate puts the flow live so it can be triggered in your org.


The last is the most important button because until you hit Activate, the flow won’t actually run in the wild. It’ll just sit there, waiting for the green light, so do all your debugging and testing before clicking it!

Bonus: Einstein for Flow


Einstein for Flow is a generative AI assistant built right into Flow Builder. If you have Einstein Generative AI set up in your org, this is a great feature to enable that can help make your life as a Flow builder easier, especially when creating new flows, as you will have the option to “Let Einstein Help You Build”.


As a beginner, having Einstein generate a starter flow using your well-written prompt can be very useful. All that’s left is to review your flow and add more customizations depending on what your automation needs!

Week 4: Flow Elements Explained

Week 4: Flow Elements Explained


If you’ve been following along so far, you now know about the different Flow Types and explored what Flow Builder has to offer. I’m sure that by now, you’ve already accepted that Flow is the hottest automation tool that the platform offers out of the box.


However, similar to how AI is only as smart as your prompts are, a Flow is only as strong as the pieces it’s made of. This week, we’re going to unpack the main building blocks: the elements that bring a Flow to life.


Flow elements are like Lego bricks. Each has its own shape and purpose, and when you snap them together in the right way, you end up with something impressive. Skip one, or use the wrong piece, and your structure doesn’t hold. To give you a clearer grasp of which piece to use (and when!), we’ll walk through each element briefly this week.The three types of elements are: Interaction, Logic, and Data elements.

Interaction


I like to call these elements “performative”, and no, not in the internet-slang way you might’ve seen floating around recently, but because these elements actually do something. They’re the pieces that, for example, show information to a user, ask for input, or take an action on your behalf. Think of them as the hands-on parts of a Flow, and their icons on the builder are blue.

  • Screen: Picture a pop-up that asks a service agent to confirm customer details or capture case specifics before moving forward. The pop-up is your screen, and it is how you gather information from users. They involve and require user interaction. This element only appears when you’re creating a Screen Flow, as expected.

Sample screen configuration

  • Action: You know how your org has quick actions or even the standard Send Email action? This element lets your Flow call on something Salesforce already knows how to do (like these actions). This could mean sending an email, creating a record with a quick action like New Task, submitting for approval, or even running a piece of custom Apex code. Instead of rebuilding those functions from scratch, you can just “plug them in” with the Action element.

Sample Case Actions that can be added using an Action element

  • Subflow: I think the name speaks for itself, like how a subtab is a tab within another tab. A subflow element lets you call another flow within your current flow. It’s great for reusing logic, so that doing the same set of automations only involves a single subflow element instead of having to build the same steps over and over. It’s like reusing a trusted recipe.

Choose from available Flows in your org to set as a subflow

Logic


If Interaction elements are the “performers”, then you can imagine Logic elements as the thinkers. They allow you to make your Flow make decisions, do calculations, or repeat steps when needed. In other words, Logic elements are what give your Flow its brainpower, and their icons on the builder are orange.

  • Assignment: This element is kinda like your Flow’s scratch pad. A variable/s (part of next week’s topic!) is like a little note your Flow keeps on the side: it holds a piece of information that you might need later. The Assignment element is how you write that note. For example, you might assign today’s date to a variable, or copy a field value into a placeholder you’ll use later. On its own, it seems like it doesn’t do much, but without Assignments, your Flow wouldn’t have a way to remember or update the little details that keep everything moving smoothly.

Sample Assignment element configuration

  • Decision: This is your flow’s “two roads diverged in a yellow wood” moment (hat tip to Robert Frost!) – the classic fork in the road. You can set more than two outcomes, and you also set the conditions for each. Sometimes it’s as simple as: if a record meets your criteria, follow Path A; if not, go down Path B. And since you’re not limited to just two outcomes, it can be powerful, but also something to watch out for, as Flows can quickly get complicated with too many branches.

Sample Decision element configuration

  • Loop: often used with the Assignment element, Loop allows you to deal with multiple variables at once. In a collection, it walks through every one. Imagine you’ve got a stack of Contacts to process – the Loop picks up the first one, runs it through the steps you’ve defined, then goes back for the next, and so on until the stack is finished.

Sample Loop element configuration 

  • Transform: I learned to use this one after painstakingly using combinations of Loop, Assignment, and Decision elements to deal with multiple records. Transform allows you to map one or more variables to a new variable/s. It’s a powerful way to map source to target data, allowing you to convert data types, map fields between objects, reformat, or even aggregate.

Sample Transform element configuration that accomplishes the same task I was trying to do with the Assignment-Loop combo from the previous screenshot

  • Collection Sort: This element arranges variables in order. When you have a variable that has a collection of records, say, Opportunities, for example, you can use Collection Sort to line them up in the order that you want according to the value in the Amount or Close Date fields. Maybe you want the biggest deals first, or the oldest ones at the top.
  • Collection Filter: If Sort is about order, Filter is about focus. This element lets you take a collection variable and pull out just the ones you care about. For example, from a collection of Contacts, you might filter out only those marked as “Active”. It’s effective for narrowing down records so you don’t have to use so many Get Records elements (we’ll get to this in a bit!) in your Flow.
  • Wait Elements: Sometimes your Flow needs to take a breather. Wait (or Pause) elements let your Flow wait until a specific time or until a record meets certain criteria before continuing. Note that these elements only appear as options in Autolaunched or Scheduled flows. We won’t dive deep into each kind here, but if you want to learn all about Wait elements and their best use cases, check out this article.

Data

  • Get Records: This is your Flow’s way of saying, “Go fetch that for me”. It is used to pull information directly from Salesforce. For example, maybe you want to find all the open Cases for a customer, or look up an Account’s details before creating a new Opportunity. The results in a Get Records element are stored in a variable, which you can use on other parts of your flow.
  • Create Records: As the name suggests, this is how your Flow adds something new to Salesforce. Some examples are a fresh Lead record, a Task assigned to a user, or a custom object record.
  • Update Records: This element takes a record that already exists in Salesforce and makes changes to it. For instance, it can mark an open Case as “Closed”, bump an Opportunity’s Stage, or update a Contact’s phone number.
  • Delete Records: Removes records from Salesforce. Like normal deletion, deleted records are sent to the Recycle Bin and stay there for 15 days before they’re permanently gone from your org. You’ll use this one carefully, but it’s essential for cleanup automations.
Week 5: Flow Resources and Variables

Week 5: Flow Resources and Variables


We’re five weeks in, and we’ve nearly explored all the main parts of a Flow. From last week’s lesson on Elements, you may have noticed I mentioned “variables” a few times. That just shows how important this week’s topic is, as elements can’t really tap into their full potential without variables.


This week, we’ll dive into Resources and Variables, or what I like to call the ‘behind-the-scenes’ building blocks that give flows their memory and flexibility.


When you first open Flow Builder, most of your attention naturally goes to the elements in the toolbox, because they’re the visible parts you drag onto the canvas. But resources are a little different. They don’t appear as shapes in your flow, but they quietly power what happens in the background. I like to think of them as seasoning ingredients you add while cooking. You might not see them on the plate, but without them, the dish wouldn’t come together.

Types of Resources

Variables


Remember back in school when x and y were used in algebra to represent unknown numbers? Using x and y in equations means you don’t know the value yet, and it can change as you solve the problem.


Variables in Salesforce work the same way – they store data you can use and reuse in your flow. You set them because you don’t know the exact value right now, so they serve as placeholders for values you expect to change or pass between elements.


The kinds of data you can put in a variable include Text, Record, Number, Currency, Boolean, Date, Time, Date/Time, Picklist, and Multi-Select Picklist.


For example, in this screenshot, I created a variable named accountID. It acts as the “container” for a source Account ID that I want to use in my flow. Since record IDs are made up of alphanumeric characters, the data type I chose is Text.

Collection Variables


If variables are like single containers, collections are like a basket that holds many of those containers. A collection variable is essentially a list of values or records. When creating a new variable, just check the box for “Allow multiple values (collection)” to turn it into a collection variable.


One important detail to note is that a collection can only hold values of the same type. For example, a text collection can only hold text values, and a record collection can only hold records of the same object (all Accounts, all Contacts, etc.). You can’t mix different objects or data types in the same collection.


These are powerful when your flow needs to handle multiple records at once. For example, you might gather all Cases related to an Account into a collection, then loop through them to update their statuses.

Constants


Just like constants in algebra represent fixed values, constants in Flow also store values that don’t change. They’re similar to variables, but with one key difference: their value stays the same. You set it once, and then use it anywhere in your flow. If you ever need to update it, you only have to change it once, and it updates everywhere you it appears in the flow.


For example, imagine you want to use your company’s standard support email address in multiple places within a flow. Instead of hardcoding it each time, you could store it as a constant called SupportEmail with a data type of Text. That way, if the email address ever changes, you only need to update the constant once.

Formulas


Formulas in Flow work just like the formula fields you know in Salesforce. They calculate values dynamically based on other data, so instead of typing in a fixed number or string, you can make your flow “do the math” for you.


For example, you could create a formula that adds 30 days to the date the flow was run, helping you calculate a follow-up date automatically. Or maybe you want to multiply a discount rate by an Opportunity Amount – a formula can handle that computation for you.


The beauty of formulas is that they’re not static, and they adapt depending on the data your flow is working with.

Text Templates


Text templates are resources that let you create and reuse blocks of text. They’re really handy when sending emails (though the newer enhanced Send Email Flow Action can handle your email content for you directly!) or setting descriptions in a record update for example.


Instead of typing out a long body of text every time you need it, you can build it once as a text template. You can even insert merge fields (like {!Contact.FirstName}) for example, so the message feels personalized. This keeps your flow cleaner and makes text easier to manage if you need to edit it later on.

Stages


Stages are used in Screen Flows to show users where they are in a guided process. Since we can now display progress indicators on a Screen element, Stage resources with progress indicators keep users informed about which stage they’re currently in and how they’ve progressed in a flow so far.


While they don’t change the actual logic of the flow, by representing the steps in your flow, it’s easier to determine how the sorting goes among other steps.

Choices


Choices are resources that represent an option for users when they’re filling out a screen in your flow. You can configure them as individual choices in radio buttons or picklists.


But if you’d like to configure your screen’s choices as a set from other sources instead of individually, check out these other types of choice resources:

  • Picklist Choice Set: Pulls values directly from an existing picklist field. For example, the screenshot below shows a picklist choice set that can be called out on a Screen Flow component to display values from the custom Expense__c picklist field in a Reimbursement Request record.

  • Record Choice Set: Generate a set of choices by using a filtered list of records. To determine which records are included in the choice set, filters can be set directly from the resource’s configuration, and then for each record that meets the filter conditions, the flow creates a choice using values from the record.
  • Collection Choice Set: Also generates a set of choices by using a list of records (like record choice set above), but this time, the record list comes from a record collection variable or external data.
Week 6: Decision Elements and Branching


So far, we’ve broken down the different parts of a flow: elements, resources, and how they all come together. But if it’s your first time trying to imagine them working side by side, I know it can still feel a little abstract. For beginners, the first flow you picture in your head usually looks simple: do A, then B, then C. If you’ve worked with Process Builder before, that straight-line structure will feel familiar.


But real life isn’t always that straightforward. Users and customers can make different choices, processes often come with exceptions, and the next step depends on the situation. This is where Decision elements shine because, as mentioned in Week 4, they are your Flow’s forks in the road: your flow asks a question, and depending on the answer, it heads down a specific path. Decision elements give your flow the structure that transforms it from a basic checklist into something more dynamic.

The Decision Element: Outcomes and Branches


Let’s break down the Decision element. The main purpose of it is to create paths for your flow to take based on specified criteria or conditions. Each path is called an Outcome.

This Decision element has four outcomes


When you configure a Decision element, you’ll start by setting the usual fields: Label, API Name, and Description. After that, you’ll define the Outcomes. By default, Salesforce gives you two paths: New Outcome and Default Outcome.


The New Outcome is the one you configure, and it’s the first path where you’ll set the conditions. Each outcome (except the default) needs its own Label and API Name, plus the conditions that should be met for the flow to follow that path.


When setting up conditions, you’ll see three options under Condition Requirements to Execute Outcome:

  • AND: all conditions must be true.
  • OR: at least one condition must be true.
  • Custom Logic: mix and match your condition numbers with operators like AND, OR, and NOT for more complex rules. This comes in handy if you want something like: “Close Date is this quarter AND Stage is Negotiation, OR Probability is over 80%.”

Sample custom condition logic


When it comes to conditions themselves, you’ll configure them by setting three things: a Resource, an Operator, and a Value.

  • The Resource is what you want to evaluate, and this could be any resource in your flow, including Global Variables (like the current running user or triggering record).
  • The Operator is how you want to compare that resource (could be equals, does not equal, greater than, contains, etc.).
  • The Value is what you’re comparing your resource against. For example, it could be a resource in your flow holding a specific Stage name, a number, or Global Constants like True or False.


So in practice, your conditions might look like:

  • [Opportunity Stage] equals “Closed Won”
  • [Escalated] equals True
  • [Annual Revenue] greater than 1000000

Sample conditions


You can add as many conditions as you’d like, as there isn’t a strict per-condition limit for Decision elements. However, keep in mind that every evaluation contributes to the flow’s overall processing time, meaning the more complex your conditions, the more work the system has to do. To keep your flows efficient, try to keep your conditions straightforward and avoid unnecessary checks.


If your flow is a Record-Triggered Flow, you’ll see an extra setting called “When to Execute Outcome”. This controls when Salesforce checks your conditions, and it might be easier to identify which one you need by asking, “Do you want this to happen just once, or every single time?

  • Only when the record is updated to meet the condition requirements (the outcome runs the moment the record changes into a matching state, meaning the flow only fires the first time the record matches the condition)
  • Example: Your condition reads “Case Priority equals High”. A Case’s Priority changes from Medium to High. The outcome is executed right at that change, because that’s when the condition became true.
  • Every time the record is updated and meets the condition requirements (The flow fires any time the record already matches the condition and then gets updated again).
  • Example: The Case is already Priority = High, and someone edits the Description field. Even though Priority didn’t change, the condition “Priority = High” is still true, so the outcome runs again.


In short, you just have to choose between “only trigger when it flips to true” and “keep triggering as long as it’s true”.


Now you’ve got your first conditional Outcome. Adding more is as simple as clicking the plus sign next to Outcome Order. Whenever you add a new outcome, you’re essentially adding another branch to your decision element. You can add as many outcomes as you need, but it’s usually best to keep them tidy so your flow stays easy to follow.


Keep in mind that order matters. Your flow evaluates outcomes from top to bottom and executes the first one whose conditions are met. So, let’s say if two outcomes could both be true, whichever is higher in the list “wins”. The good news is you can easily rearrange outcomes by dragging them into the order you want.


And if none of the conditions are met, we finally have our Default Outcome. This one’s the easiest, no conditions required! It’s like your safety net, or the “everything else” path. You can relabel it if you like, but you don’t have to configure anything for it to work.

Tips for Decision Elements


Here are a few tips to keep your Decision elements clear and reliable:

  • Name outcomes clearly: When I was first learning Decision elements, I used labels like “Outcome 1” or “Path A”. That works fine in the moment, since you already know what you’re building toward. But fast forward a few months, and trying to understand that same flow can turn into a nightmare when making sense of each path means you’d have to click into each outcome just to see what the conditions were. Save yourself (and others) the headache by using meaningful names like “Closed Won Path” or “High Priority Escalation”. Clear labels make flows easier to understand and maintain, both now and later.
  • Order outcomes with intention: The order of outcomes isn’t random, as your flow checks them from top to bottom. Be deliberate with the way you arrange them by thinking about how each condition relates to the others and making sure one branch doesn’t accidentally “steal” records meant for another. In some cases, that might mean putting very specific conditions first. In others, it might make sense to put a more common condition higher so it’s evaluated sooner. The important thing is that the order reflects your process logic, and not just the order you created them in.
  • Test edge cases and every possible outcome: When you’re setting up your Decision element, do try to think about not just the common scenarios, but all the possible ones. Every single value or scenario that could come through should have a clear path. And then ask yourself: what if none of these expected values show up? Configure the actions for your Default Outcome path as needed. It acts as a safety net to catch anything you didn’t explicitly plan for.
  • Consider a Formula resource for complex logic: If you ever find yourself stacking too many conditions into your Decision element, it might be a sign to step back. Instead, try building a formula resource that evaluates your logic in one place. This way, your Decision just has to check whether the formula returns True or False, and it saves you time reviewing complex logic and long lists of conditions later on.
Week 7: Why Loops, Collections, and the Transform Element Matter


We’ve already tackled the “whats” – what a loop is, what a collection is, and how they work individually. This week, we’re focusing on a common practice and use case: bulkifying flows and why these elements are almost always used together to accomplish that.


And where does the new Transform element fit into all this?

Why Loops and Collections Work Hand-in-Hand


On its own, a loop is simple. It lets you go through records one at a time. That sounds fine – so naturally, your first instinct might be to use it for updating multiple records at once. After all, it sounds perfect for that! So why not just drop an Update Records element right inside the loop?


And technically, that does work. Your flow will run an update for every record. But this is a trap, because it’s one of the fastest ways to hit governor limits. Instead of one clean bulk update, you’re suddenly running dozens of tiny updates because every single time your flow goes through a record in that loop, the Update Records element is executed.


Specifically, Salesforce only allows 150 database operations (DML statements) per flow transaction. Each data element (like Update Records) that’s fired triggers one DML statement. Since each Update inside a loop will count as a separate DML statement, updating 150 records this way would already max out the limit! If a 151st record comes along, your flow will fail and roll back.


This isn’t the week to dive deep into Flow limits, but here’s the key thing to remember: the same limits that govern Apex also apply to Flow. Even though Flow feels more declarative and more like “clicks not code,” everything you build still runs as code behind the scenes, so it makes sense that Salesforce enforces the same rules on both. Best practices (like bulkifying) matter just as much for admins as they do for developers!


With that said, “Where do we put the Update Records element then?” you might ask. This is where collections become useful. So instead of putting your data element in the loop, you:

  • Start a loop on your records.
  • Use an Assignment inside the loop to apply your changes and set variable values.
  • Add those to a new collection variable.
  • After the loop ends, run a single Update Records on that whole collection.


Check out this example on the same concept, but using the Create Records element as the ultimate data action after the loop.


The example above shows a loop that goes through each uploaded file on a Screen element. For every file upload, the Assignment element’s job is to set values for variables that are needed in creating a new Content Document Link record. It then collects those values and adds them to a new collection variable (ContentDocumentLinkCollection in the screenshot below).


Once the loop is done with the last record, the Create Records element then proceeds to use the values in the new collection variable to create Content Document Link records. This isn’t a simple or straightforward example, so for full context on this use case and process, check out my deep dive on uploading multiple files via Screen Flow, where I also explain how file attachments work in Salesforce.

Bulkifying Matters


“But I only plan to do this record update for a maximum of five records!”, you might say.


If you’re just building flows for a handful of records, I know it’s easier to take the simpler route. With no need to do assignments or make new collection variables, bulkification in the way I explained might feel like overkill. But trust me, it’s one of those things that matters before you run into problems in the future. Here’s why:

  • Limits are real: Salesforce sets limits for how many database operations you can run in a single transaction. Bulkifying ensures you don’t hit those walls.
  • It runs faster: A single update on 200 records is quicker than 200 tiny updates – otherwise, you risk what some folks call “death by a thousand cuts” (no relation to the Taylor Swift song, but it does sting just as much!)
  • Future-proofing: Your flow may only handle a few records today, but what happens when your org scales as your business grows? Five records may quietly grow to 20, and then to a hundred when the need arises. It wouldn’t be smart only to start handling limits then, right?


So start thinking in bulk! Any time you’re about to put a Data element inside a loop, stop. Ask yourself, “Can I collect all these records and update/create/delete them once instead?” Most of the time, the answer is yes.

A Loop Is Not Always the Answer


Loops, assignments, and collections are the classic way to bulkify your flows – but they’re not the only way. And not every situation needs a loop! It’s easy to get a little trigger-happy with loops (and other elements), especially once you’ve just started to feel confident connecting and using different parts for various scenarios. I’ve been there myself: sometimes I catch myself overcomplicating a flow just because I can.


The simplest approach is usually the best. A leaner Flow means fewer elements to process in the first place, so there’s even less chance of hitting limits, and even fewer unnecessary actions overall. A good rule of thumb is to start with your entry criteria by making sure only the right records enter the flow in the first place. That way, you might not even need a loop at all! Check out this article on best practices and examples for using loops in Flow.

Getting Familiar With the Transform Element


Now for the new kid on the block!


We’ve already talked about how loops and collections are the go-to way for bulkifying. At first glance, Transform almost feels like it was built to replace that entire pattern, and in some scenarios, it can. Especially when you’re mapping fields across objects, Transform saves you from juggling multiple assignments inside a loop.


Here’s what it does in practice:

  • Point to your source data (say, Opportunity records).
  • Map their fields to a target object (Cases, for example).
  • Instantly get a new collection of variables ready to be used in a Create Records element to create Cases.


If we were to connect this to our example earlier on creating Content Document Links, here’s how the same process would look like but with a Transform element:


The Source Data column (on the left) is where you pull from. In this case, that’s a collection from a Get Records element, plus data from the created record in a Create Records element. Essentially, we’re grabbing record IDs from both. The Target Data column (on the right) is where you configure your output. I set it up as a collection of Content Document Link record variables.


Mapping is the easy part. Just click the field in the Source Data column so it highlights, then click the matching field in the Target Data column. A line appears to show the connection… and that’s it. You’ve just mapped fields without building a single assignment.


Easy, right? But here’s the important part: Transform doesn’t mean loops and collections are outdated. It’s just another tool, and besides, Transform is more than just a replacement for bulkifying with loops and collections. You can also use it for preparing data for integrations, or restructuring records for a Screen. It’s a reshaping tool, after all.

Loops and collections are reliable and valuable because once you understand them, you’ll start spotting patterns everywhere that need them. On the other hand, the Transform element is a fantastic shortcut for some scenarios that may call for bulkifying with loops and collections, but it doesn’t necessarily replace the old tools. Rather, it complements them!

So next time you’re building, don’t just think about what you’re doing. Ask yourself why you’re doing it that way, and whether another element might fit better. Of course, there isn’t always a clear-cut answer, and there’s always a whole world of factors to consider when deciding on what to use.

Advanced Flow logic, performance tuning, and governor limits are part of that conversation – but that’s a topic for another day. For now, getting comfortable with these building blocks will put you miles ahead.

Week 8: Building Screen, Record & Schedule Triggered Flows


Way back in Week 2, we discussed the various Flow types you can build with the builder, as well as when to use each. Those were their textbook definitions and how they compare to one another. However, knowing what they are and actually building them are two very different things.


This week, we’re shifting the focus onto the three flow types you’ll probably spend the majority of your time with: Screen Flows, Record-Triggered Flows, and Schedule-Triggered Flows. These are the everyday workhorses of automation. On the surface, these flow types are easy to tell apart, so they seem pretty simple to get started with.


But like anything in Flow, the challenges and pitfalls usually show up once you’re actually building or when they face your users – not because the flow type itself is tricky, but because of the design decisions you make along the way.


Instead of re-explaining what these flows are, we’re getting “in the trenches” with tips and small design choices that can save you a lot of headaches later.

Screen Flows


Screen Flows are the most visible kind of flow, because what sets them apart is the Screen element. It’s their defining feature, and your users will interact with it directly by clicking through, filling out fields, and (hopefully) completing what you’ve asked them to do. Everything seems easy enough… until someone gets frustrated with the design.


One common mistake early on is thinking that more screens equate to more clarity. After all, in design, we’re often told that a clean and uncluttered interface is the best way to hold someone’s attention. This mindset can sometimes make it tempting to break a form into several smaller screens with only a few fields each. But in reality, fewer screens usually mean a smoother experience. If you’ve ever abandoned a form halfway through because it felt endless, you’ll know why this has bearing.


A couple of things to keep in mind:


Keep it light. Strive for balance by not cluttering your screen, but at the same time, don’t split one form into too many screens either. It helps to use conditional visibility to only show fields when needed, or reactivity for even more granular control on how you want the fields on your screen to behave, depending on a number of factors.


Also, plan for abandonment. Even with a well-designed screen, you can’t count on 100% completion every time. What happens if a user closes the tab halfway? It would be nice to offer your users the ability to know where they are in a process using progress indicators on your screen, or add the ability to Pause.


Placement is everything, because a well-designed flow won’t get used if it’s hidden away anyway. Think about context, like should it live on a record page, a home page, or be triggered by a button? Where would a user experience screen ease your users’ effort? Put it where they naturally need it!


The key takeaway here is to build with the user in mind. Put yourself in their shoes and think:

    • When filling out the form, what would you want to see first? Put those fields at the top.

    • What information would frustrate you if it were missing from the record later? Make those required.

    • Beyond the individual record, what will the business need for reporting and KPIs? Be sure the fields critical for measurement and analysis are captured reliably.

    • What details are only sometimes relevant? Hide them until needed with conditional visibility.

    • What components could help make the screen more efficient and user-friendly?

    • If something goes wrong, what kind of error message would help you understand what’s going on?


We’ll dig deeper into that last one next week when we cover error handling and fault paths, so stay tuned!

Record-Triggered Flows


Record-Triggered Flows do their job quietly in the background, which I believe has the potential to be both a strength and a danger. The number one trap I fell into early on (similar to when I was starting with Workflow Rules and Process Builder as well) is setting them to run simply “every time a record is updated”, without realizing that meant every change, even if it was something trivial.


That’s a recipe for unexpected results because this means that regardless of the change, your automation is triggered, whatever small thing is being done to the record. You could be running automation on something completely unrelated every single time the Case status is updated! Yikes.


So the key here is to be specific with entry criteria. This applies to flows in general, but it’s especially critical for record-triggered ones. Don’t just say “when a record is updated”, evaluate whether:


A flow that updates a record, which then triggers itself again, can spiral out fast. Guard against infinite loops! For instance, you might be creating a record-triggered flow on Opportunities that runs whenever there is any update to it, like Stage changes, for example. Inside the flow, you set it to update a custom “Stage Comments” field. But because the flow is also updating the Opportunity record itself, that update triggers the same flow again. Without conditions in place, you’ve just created a feedback loop where the Opportunity keeps retriggering its own automation.


You can prevent situations like this by using ISCHANGED() as a condition to check whether specific fields have been updated, or by setting proper entry conditions.


Watch out for conflicts. This is crucial, especially in multi-admin and more complex enterprise orgs, because the automation you’re building may not be the only one that touches that object. Two flows, both updating the same field, can cause some very confusing outcomes, and this is also why it’s important to fill out those descriptions! This falls into general flow best practices on keeping naming conventions and documentation, but it does help a lot in this regard. For more insights on what to keep in mind when creating Record-Triggered flows, check out this article on structuring your RT flow strategy.


And lastly, know the difference between Before-Save and After-Save flows, because this is one of the very first things you need to define when starting to build your flow.

Schedule-Triggered Flows


On paper, Schedule-Triggered Flows sound amazing. After all, their main purpose is to take routine tasks off your plate – fewer things to worry about! In practice, though, they’re trickier than they seem. The biggest catch is volume, because it’s easy to underestimate how many records your flow might pick up once it actually runs. For example, running an automation daily might seem harmless until you realize your broad criteria caused hundreds or thousands of updates overnight.


As best practice, it’s better to narrow things down right at the entry criteria of the scheduled flow, rather than starting broad and relying on a Get Records element inside the flow to filter things later. I see this as similar to using a Data element inside of a loop, as discussed in last week’s lesson – think of your flow executing that Get Records element for every instance a record passes your broad entry criteria. It ends up fetching records again and again, which can hurt performance and even risk hitting limits. Your entry conditions act perfectly as your built-in “get”, so that way, Salesforce only collects what you actually need from the start.


The key here is to be intentional. It can make all the difference! One example is to use some sort of control field, like a checkbox or date stamp, to mark “already processed” records.  Without this, you risk reprocessing the same records again and again, which can hammer your system and confuse your users. For instance, imagine you build a schedule-triggered flow to send reminder emails for Opportunities that haven’t been updated in 30 days. If you don’t mark those Opportunities as “reminder sent”, the flow will grab the same records every time it runs, and that can result in your sales team getting the exact same email every morning!


I used this same idea in this step-by-step guide to creating a schedule-triggered flow, where the flow deactivates users who haven’t logged in for 60 days. Notice that in one of the decision outcomes, the flow updates a checkbox to flag that a warning email was already sent to the user.


Also, don’t overschedule just because you can! Nightly runs may seem necessary depending on the use case, but think about the real purpose of your automation first, as many processes are fine on a weekly or even monthly cadence.


Finally, mind the time zone, especially for businesses that have users from different regions. Salesforce runs schedule-triggered flows in your org’s default time zone. If your users are spread across regions, that 2 AM run might actually hit during someone’s peak working hours, and nothing’s worse than records shifting under people mid-task.


Schedule-triggered flows are powerful, but they’re also easy to forget about… until something breaks! Just like a sprinkler system, they’re great when they turn on as planned, but can be a real mess if you don’t check where the water was going first.

These three flow types may feel basic, but they’re also the foundation of so much Salesforce automation. Anyone can add elements onto a canvas, but what makes you a strong builder is learning the little habits that prevent problems before they start.

Being intentional while building is always the way to go, and with more practice, it starts to build muscle memory. Mastering these habits now will pay off big when you move on to more complex flows later on.

 

Week 9: Error Management and Fault Paths


By this point, we’ve talked a lot about building flows, making them work the way we want, and applying them to parts of the business that need automation. As with anything, practice helps you improve – but if we’re talking honestly here, even the cleanest, best-thought-out flow can (and will) fail at some point. For some reason, maybe a user or a record isn’t there anymore, or maybe the user running it doesn’t have the right permissions, or your flow may be hitting governor limits.


Whatever the reason, Salesforce doesn’t exactly whisper a gentle warning or spoon-feed you an extremely detailed account of what went wrong and how to fix it. Most times, it just throws up one of those classic cryptic error messages (hello, “unhandled fault”?) and stops, after which the last admin who modified the flow gets an email with more info on what happened. This is obviously not really a great experience for end users, right? Because these errors can cause confusion, it usually means more headaches for you when the users come knocking.

What Are Fault Paths for?


A fault path is like your alternate branch or backup plan, and it connects to parts of your flow that may fail, like data elements or actions. Normally, when your flow runs a “Get Records” or “Update Records”, it keeps going as long as everything works. But if something goes wrong, for example, the record can’t be found or the user doesn’t have access, your fault path’s role is to give the flow a chance to follow a different branch instead of failing.


I know, I know. Right now, especially if your flow is pretty simple, it’s tempting to skip error handling. It’s easy to feel confident that your flow “should” work. But oftentimes, real life in Salesforce is messy. Data isn’t always clean or perfect, users and their permissions change, and people can click buttons you didn’t expect them to. No matter how simple your flow may seem, it’s always good to consider setting up fault paths because, without them, when something breaks, the situation can cause users to stop trusting your flows.

What Can You Do With Fault Paths?


The main point to accept here is that these fault paths don’t prevent the error from happening. What you can do is manage how that error shows up. A clear error message keeps the user from feeling lost, while a log or notification gives you a trail to follow when it’s time to fix things. Over time, this is what builds trust. People are more likely to embrace your automations when they feel like the system has their back, even when something goes wrong.


What you do with it is up to you. The most common one is to firstly, show the user a friendly error message that actually makes sense instead of just “An unhandled fault occurred”.

The dreaded unhandled fault error is nothing but vague and frustrating.


This can be done by designing an error screen that shows the user an error message calling out the global variable {!$Flow.FaultMessage}. This is made to show a more detailed error, and despite being more technical and your user probably not having the tool to fix it, they at least get more context as to what actually went wrong.

Example of a screen element that uses a custom message + the flow fault message global variable.


You can see how I applied this in the flow we built together in this article. See how the message below shows the custom error along with more details as to why the error came to be (in this case, the flow hit a validation rule).


However, that’s not all you can do with fault paths! Check out the table below for an idea of what you can apply to your automations:


CapabilityWhat You Can DoReason to Use It
Show a user-friendly error messageIn a Screen Flow, connect a fault path from a Data or Action element, like a Create Records or Update Records, for example, to a Screen element that displays the {!$Flow.FaultMessage} global variable within a custom message. It would also be nice to advise the user that the admin has been notified of the error.The default “An unhandled fault has occurred” message is vague and may cause your users frustration. A clearer message helps them understand what went wrong, like the Flow may have hit a validation rule, etc.
Log the error internallyUse a fault path to Create Records in a custom object that you can name anything you want, like Flow Error Log, for example. This can be another place to use the {!$Flow.FaultMessage} global variable to display the error details, along with other things you might want to be able to view at a glance.While you can also view paused and failed flow interviews in Setup > Paused and Failed Flow Interviews, or see errored flows in the Automation app, creating a custom object record for errors in your fault path preserves details of what failed alongside other information that your business would like to see, so admins can report on, review, trend issues, and debug later on.
Send alerts/notificationsFrom the fault path, use an Email action (or other notifications) to send error details to admins or support teams.By default, the last admin who modified the flow receives a notification email when an error occurs. You can send notifications or emails to other users by adding the needed actions to your fault path. Especially for background flows or nightly automations where you may not notice failures immediately, this can be useful.
Call SubflowsInstead of replicating error-handling logic everywhere, you can attach the fault path to call a reusable subflow that handles error logic (like an autolaunched flow that does any of the capabilities above, for example).This promotes consistency and saves maintenance effort and manual creation of the same actions over and over. For instance, a change in error handling in one subflow automatically applies everywhere that subflow is called.

So even if errors in flows are unavoidable, how you handle them will make all the difference. A thoughtful fault path and a user-friendly error message will let your users know your automation can be trusted, the system isn’t broken, and your flow just hit a bump in the road!

When it comes down to it, consider error management more than just a technical best practice, because it’s giving both you and your users a smoother, less frustrating experience.

Week 10: Debugging Flow


If there’s a topic we’re going to exhaust in the last few weeks of this Flow learning journey, it’s the tasks you need to do before actually deploying your Flow into production. These steps are just as important as the actual building process.


Last week, we discussed that things rarely work perfectly on the first try – and that’s okay because fault paths are there to help! Another huge part of becoming comfortable with Flow is learning how to debug and test. Whether you’re building something simple like an automated email alert or even a more complex record-triggered flow that involves multiple objects, you’ll eventually encounter a situation where something doesn’t behave as expected.


The good news is that Salesforce’s latest releases have focused on the Flow Builder’s debugging tool. With plenty of new features designed to help ensure your flow runs exactly as intended, let’s dive in.

What Debugging Is


I like to think of debugging as a bit of detective work. Even in the literal sense, the word itself gives it away: “de” meaning to remove and “bug” referring to an issue, right? Debugging, then, is about removing issues or figuring out why your flow isn’t behaving the way you expected.


When you’re working with complex flows, there can be so many elements, paths, decisions…that’s a lot of possible culprits! Maybe your condition logic isn’t being met, a variable didn’t store the right value, or a record update quietly failed – debugging gives you visibility into what’s actually happening “under the hood”, so it’s easier to trace where things might have gone off track.

Debugging in Flow Builder


Let’s say you’ve finished building your flow, as in every element and every fault path is all set. When you click Debug in Flow Builder, Salesforce opens the Debug Panel on the left and lets you simulate how your flow will run.


Your flow on the canvas remains visible on the right side of the screen, so you can easily go through element configurations and figure out what changes may be needed. Clicking into an element opens up its configuration on the right side as usual, opposite the debug panel on the left.


The initial options available on the Debug Panel depend on the type of flow you’re working with. For instance, in a record-triggered flow, you can choose which record will trigger it. You’ll also see other options, such as whether to commit changes to the database, run the flow as another user, set input variables, or skip the start condition requirements.


Once you’ve completed the initial debug setup, click Run. This executes your flow based on the conditions you’ve defined. When it finishes, check your canvas to see which path the flow followed by tracing the bold line that appears.

The triggering record in this sample flow turned out to be a high-value claim. The bold line shows which path it took, making it easy to follow which decision outcomes were taken along the way.


On the panel is where you’ll find more information, like:

  • Whether or not the start conditions were met.
  • Which elements executed successfully.
  • Which decision outcomes were taken.
  • The values assigned to your variables.


These details are displayed in the order they occurred, so it’s easy for you to trace your flow’s exact sequence of events. If you find that the bold line on your canvas ends somewhere unexpected, check the panel for the finer details, as it’ll show you where things might have taken a wrong turn.


Each step in the flow run appears in its own box. To view more information about a specific step, click the arrow dropdown to expand it. Let’s take a look at how to read these details.

Parentheses


When a value appears in parentheses, it represents the value for that field. In the example above, “Status__c (Approved)” tells us that the triggering record’s status is Approved, while the start conditions require the record to have any of the following statuses: Approved, Incomplete, or Rejected. From this, we can already infer that the record met the start conditions – which is why we see the message, “The triggering record met the start conditions.” at the top.


The same is true for this one, where it appears that the Amount__c field for the triggering record is 500. The executed outcome is Mid_Claim, where it satisfies the conditions: greater than or equal to 100, but less than or equal to 500.

Data Element Results


For your data elements like Get Records, Create Records, and so on, I particularly like how the expanded details almost read like a SOQL query. It’s as if the debugger is showing you exactly what it did behind the scenes to retrieve or create data. For example:


The above example shows how the Mid Claims Queue ID was retrieved.


I do notice the way details are written might look a little plain – readable enough, but not exactly beginner-friendly. If you’re familiar with SOQL, you’ll probably recognize the pattern right away and find it quicker to interpret. For everyone else, it might take a second longer to mentally separate the fields, operators, and values since the formatting doesn’t highlight them.


Personally, I think this could be easier on the eyes if Salesforce added a bit of visual distinction, for example, bolding field names, italicizing operators, or using subtle color differences. That said, the most important thing is that it tells me what I need to know, so I’ll take it!


Here’s another example, but on an Update Records element:


This section conveniently displays the final, updated values of the fields on the triggering record. While they’re mostly Ids, it’s still a faster way to verify results compared to running the flow live!

Panel Preferences


Another thing I really like about the Debug Panel is that you can set your own viewing preferences – just click the small gear icon!


If you prefer seeing elements by their API Names instead of their labels, you can easily switch that on.

Notice how the Update Records element here is displayed using its API Name, which explains the underscores. Otherwise, this would’ve simply shown as “Assign to Mid Claims Queue”


Turning on the option to display governor limit consumption is another useful one! Normally, you wouldn’t notice these limits until something breaks, right? But here you can easily see how much of your limits the flow is consuming.


And while we’re on the topic of preferences, don’t forget that you can easily expand the panel to its widest with just one click, or drag to resize to a custom size.

 

Debug Logs


If you ever need a copy of the debug results outside of Flow Builder, say, for documentation, troubleshooting with another admin, or maybe sharing with your developer, you can easily grab a complete text version. Just click the clipboard icon in the upper-right corner of the Debug Panel.


From there, paste it into your notes or a text editor so you can review it later, share it with your team, or keep it for reference when comparing runs. It’s a small feature, but one that’s super handy when you’re trying to track what went right (or wrong) in your flow.

Sample of how the debug log text looks when pasted into Notepad.

What About Screen Flows?


Screen flows can be debugged too! The Debug Panel opens on the left side as expected, but the right side now has two tabs: one for your screen and another for your flow canvas.

Debug panel on the left, screen on the right. No details on the debug panel yet because no input values have been entered on the screen.


You can switch between the two tabs to see both what the user experiences and what’s happening behind the scenes, which makes it a great way to trace how your screen inputs translate into flow actions in real time.

Debugging might not sound as exciting as building the flow itself, but it’s one of those steps that separates a working automation from a reliable one. Taking the time to understand how your flow behaves behind the scenes helps you catch small mistakes before they snowball into bigger issues in production. And with the enhanced Debug Panel in Flow Builder, it’s easier than ever to see exactly what your flow is doing at every step.

Week 11: Testing Flow


We’ve covered the technicalities of error handling and debugging so far, but we’re not quite finished! You know how there’s always that ongoing debate between being reactive vs. proactive? Well, debugging alone sits on the “reactive” side of things.


What I’d like to focus on this week is how to start having a proactive mindset. And even if it seems like it, taking action doesn’t start after you’re done building your flow. It starts even while you build. Every element you add to your flow should be intentional and with testing in mind long before you hit Activate.

Debugging with Intention


When I first started with flows, I had no testing strategy at all. To me, it was simple enough to build, activate, and hope for the best. And sometimes, after activating, I’d even test the flow behavior using dummy records in production (I know, I know. Don’t do this!).


When things broke, I couldn’t figure out what part of my complex flow went wrong. That experience taught me an important lesson: the earlier you realize “it works on my machine” isn’t good enough when you’re building for an entire org, the better.


You know how they say “prevention is better than cure” when it comes to health stuff? That absolutely applies here, too. I consider debugging as medicine, while testing and being intentional are prevention. Even if both of them are important, the latter saves you a lot more headaches in the long run.

A Testing Mindset


The first shift you need to make is in the mind. When you finish building a flow, you never know for sure whether or not it will work unless you’ve done some testing throughout the build. While you add in your elements, try asking yourself:

  • What assumptions am I making about the data?
  • What happens if those assumptions are wrong?
  • What’s the worst-case scenario?


That last one might sound generic, but it’s key. Once I started always having the worst-case scenario in mind, I’ve learned to think like a pessimist when testing, because there are countless ways a flow can fall out of rhythm. It may sound dramatic, but real-world scenarios are messy, and your automation needs to be ready for that. When data doesn’t follow the rules, or when integrations fail, testing with intention means preparing for that chaos before your users ever experience it.

The Three Layers of Intentional Testing


Testing can be divided into three layers. Each layer catches different types of problems, and you need all three to feel confident your flow will hold up.

Layer 1: The Happy Path


Ah, everyone’s favorite! And it’s also where most people stop.


The happy path is the ideal scenario where everything goes right. Meaning, the data is clean, the user has all the right permissions, and every element in your flow executes exactly as you designed it. Sure, testing the happy path is important, but it’s not enough.


“Why? Isn’t this already proof that it works?”, you might ask.


Here we could use a metaphor, say, shopping for your first car. You can take different cars for a test drive while hunting for the perfect one, but what are you really testing if you only drive them on straight, smooth, empty roads? What happens when you hit a pothole, get stuck in traffic, drive in the rain, or take it up to the mountains with those outrageous inclines?


Obviously, we couldn’t ask all car dealerships to provide test-driving scenarios with such outrageous conditions, but you get my drift. With flows, though, you actually do have a bit more control. You might not be able to simulate every possible error, but you can definitely create scenarios that push your flow beyond the happy path.


When testing the happy path, think in sections. Break your flow into smaller chunks and identify checkpoints where you can use the Debug button to confirm that:

  • Your data elements are actually pulling in the correct records.
  • Formulas return the expected values.
  • Variables are getting populated accurately.
  • Your flow is going down the correct decision outcome.


If your flow can’t pass the happy path test, you’ll want to address those issues first before moving on to more complex scenarios.

Layer 2: The Edge Cases


This is where intentional testing really begins. Edge cases are the scenarios you didn’t design for but will absolutely happen in production.


It’s not enough to test that your flow works as expected, because you also need to confirm that what shouldn’t happen, doesn’t happen. In software development, this is referred to as negative testing, where one deliberately exposes the automation to unwanted conditions to see how it handles errors and make sure it doesn’t yield unintended results.


Here are some common scenarios you should keep in mind, and some questions you might want to ask yourself while you build:

  • Missing or null data: What if a field your flow relies on is blank? What if a Get Records element returns zero records? Test your flow with incomplete data, and counter that with your best friends: ISBLANK, ISNULL, or ISEMPTY.
  • Data Volume or Bulk Behavior: What if your flow triggers on ten records at once instead of just one? What if hundreds or thousands of records match the criteria? Make sure your flow handles “bulk” volumes appropriately (we’ve discussed bulkifying in the previous weeks) or keep your entry criteria strict. Every org grows over time, so always build with the future in mind.
  • Permissions or User Access Issues: What happens if the user running the flow doesn’t have the same permissions you do as an admin? Maybe they don’t have access to certain objects, fields, or record types? What if the flow tries to update a record that the user can’t edit? Keeping this in mind or testing with reduced privileges helps reveal these permission-related issues.
  • Integration Failures: What if your flow depends on a callout to an external system and that step fails or returns an unexpected result? What if a subflow fails, or there is an error that stops the transaction?
  • Environment Differences: What works in a sandbox may fail in production because of differences in data or other org-specific metadata. Part of your test plan should be to ask, “Does the flow function in the target environment with its data and metadata?

Layer 3: The User Experience


This layer is about testing your flow from the perspective of the people who’ll actually use it. This is worth its own layer because most of the time, your users don’t think like you do as an admin/builder. They don’t know what you intended, and when they click those buttons, they expect things to work.


First consideration is always the users’ permissions. A flow that works perfectly when you run it as an admin might fail when a standard user tries it. Since admins have the usual “View All” and “Modify All” on most objects, it can be easy to overlook this. Debug’s “Run automation as another user” option can be used to test this.


When you’re building a Screen Flow, pretend you’re the user. Make sure it’s clear what’s supposed to be done, and the field labels are obvious enough. Is the flow too long? Does it feel intuitive? Flows can be perfect in the technical sense, but end up confusing for the end user.


If you’ve set up fault paths (and you should have!), actually trigger them. I used to always make sure it hit a validation rule, just to see if it shows the expected error. Check if your error messages make sense to someone who isn’t you: a good error message tells the user what went wrong and what they can do about it, or at least provides context.

Using Debug Mode Effectively


Even with all three testing layers covered, the Debug tool is your best friend for validating how your flow behaves behind the scenes. Here are a few habits to make the most out of it:

Rollback Mode


When you’re testing, enable rollback mode. This undoes any changes your flow makes, so nothing is permanent. You can test freely without worrying about cleaning up afterward or messing up any important records!

Check Variable Values at Every Step


Don’t always assume your variables hold what you think they do. Click through the debug results and verify. Is that collection actually populated? Does that formula return the value you expected? Is that Get Records element finding the right records?

Pay Attention to Execution Paths


When your flow goes through a Decision element, Debug mode shows you which path it took and why. If it’s not following the path you expected, you can see exactly which condition failed.

Watch for Performance Issues


Debug mode doesn’t show exact execution times per element, but it shows how long the flow took to finish. Pay attention to how your flow behaves during testing, because if it feels slow or takes noticeably longer to complete, that’s a sign to check for inefficient loops or overly broad Get Records elements.

You might feel like a paranoid admin by this point, and that’s okay! Testing with intention might look like paranoia, but it really is just about being prepared.

The inevitable truth is that flows will encounter unexpected scenarios, and data can be messy. Users may do things you didn’t anticipate. It’s just the reality of things, and something as seemingly small as changing your mindset is the key to not seeing a broken flow as failure.

What separates a good flow builder from a great one isn’t avoiding problems altogether (though that does sound ideal!). It’s anticipating them, testing for them, and handling them before they ever become problems at all.

Week 12: Deploying Flow and Best Practices


Can you believe it?! We’re down to the final week of this Flow learning journey! We’ve pretty much covered all the basics, including the technicalities of building, as well as best practices or things to keep in mind when it comes to error handling and debugging. All that’s left now? Well, it’s to activate, deploy, and actually use your flow.


This week, we’re covering the final checklist before deployment and the best practices that will make you a more confident and effective flow builder.

Deployment: The Final Step!


Deployment is where everything comes together.


To me, deployment gives this feeling of both excitement and tension because it’s the moment of truth. It’s definitely exciting, but also one of the most delicate stages in automation. Even if you’ve done your best building your flow, putting up fault paths, and debugging with intention, a flow that runs perfectly in a sandbox can still break in production if you’re not careful.


This is where preparation and best practices really pay off, because it helps you deploy with confidence, avoid disruption, and make sure your automation performs exactly as intended once it reaches your users.

Preparing for Deployment


Before you hit Activate or deploy a flow to production, take a step back and make sure everything’s ready for real-world use. I like to think of this sort of like a pre-flight checklist – making sure everything’s in order before takeoff.


This is also a good time to review whether you’ve followed best practices throughout your build. Deployment sometimes feels like it’s only about clicking Activate, but it isn’t just about pressing a button – it’s about ensuring your flow is stable, reliable, and user-ready.


Here are some practices to keep in mind before taking your flow live:

1. Review Your Flow’s Metadata


This might sound boring, but really, future you (and others) will thank you for this.

  • Flow Label and API Name: Make sure your Flow label is clear and descriptive. “My Flow” or “Flow 1” might make sense to you in the moment, but in six months, when someone (or even yourself) needs to find this flow among dozens of others, it won’t be helpful. Use names that describe what the flow does and where it’s used.


Some examples are:

  • Opportunity – Send Reminder Email on Stage Change.
  • Case – Escalate High Priority to Manager.
  • Account – Create Default Contact on New Record.


The API Name is generated from your Label, but you can edit it. If you must change it, remember to keep it concise but meaningful. And once your flow is active and being referenced elsewhere, remember that changing the API name can break things, so get it right early.

Sample flow with a useless name

  • Description: I know, I know. Description fields outside of Flow aren’t always filled out. Best practice is to fill them out, but I know it’s easy to be lazy and not do it. In Flow, it seems optional (and technically it is), but a good description is one of the most valuable gifts you can give to future maintainers of your flow, including yourself.


Your description should include:

  • What the flow does (the purpose).
  • When it runs (the trigger or how it’s launched).
  • Any important context (business requirements, connected processes, known limitations).


For example: This flow runs when a high-priority Case is created. It schedules a reminder email to be sent to the Case Owner 2 hours after case creation. 


Keep it, again, concise but meaningful. Make sure to provide important context. Keep in mind that this practice isn’t limited to the flow description, but also descriptions for your various flow elements as well.

  • Element Names: When you look at your flow on the canvas, can you tell at a glance what each element does?


If your Decision elements are labeled “Decision 1”, “Decision 2”, etc., or your Assignment elements are all called “Assignment”, stop right now and rename them. Good element names make your flow self-documenting. When you (or someone else) comes back to this flow in three months, clear labels will make it infinitely easier to understand what’s happening.


Example: Instead of “Decision 1,” try “Check if Opportunity Amount > 100000.”

2. Double-Check Your Entry Criteria and Filters


Before deploying a Record-Triggered or Schedule-Triggered Flow, review your entry criteria one more time and ask yourself:

  • Is this as specific as it needs to be?
  • Could this accidentally capture more records than intended?
  • Are there any edge cases I haven’t considered?


I know you may have already touched on this during the testing phase, but one last look can save you trouble or confusion later on. The tighter your entry criteria, the more predictable your flow will be (and we want that).


While we’re on the subject of double-checking, it would be good to review object and field permissions as well. This is especially important if your flow will be used by people with different profiles or permissions.


Check that:

  • Users have access to the objects involved in your flow.
  • Required fields in your flow are visible and editable for those users.
  • Any custom objects or fields have the right permissions set.

3. Check Run Context (User vs System Mode)


Have you verified whether the flow should run with the user’s permissions or should bypass them?


This isn’t for common use cases, but if you choose to run your flow in System Context without sharing, make sure that elevated access is intentional, documented, and doesn’t create data-security holes.


You can control this in the flow’s Advanced settings. Make sure you’ve selected the right option for your use case, and understand the implications. For example, if your flow needs to update records across the entire org regardless of ownership, system context without sharing makes sense.

Activating vs. Deploying


Deploying a flow and activating it are two different things.

  • Deploying means moving the flow from one environment to another, as in from Sandbox to Production, for example.
  • Activating means making the flow live so it can actually run.


When you deploy a flow from Sandbox to Prod, it arrives in the target Prod org as inactive. You still need to open it in Flow Builder and click Activate. This is actually a good thing because it gives you one last chance to review the flow before it goes live.

Monitoring and Communication Post-Deployment


Congratulations! You’ve deployed and activated your flow. But…your job isn’t quite done yet.


In the days and weeks after deployment, keep an eye on your flow’s performance. You can go to Setup > Paused and Failed Flow Interviews to catch any errors early on.


The Setup Audit Trail can also be useful for troubleshooting unexpected changes. I used to check here first back when I was in support, and it often helped me spot when something had been modified without anyone realizing. Set up Flow Error Notifications so you get alerted immediately if something breaks (Setup > Process Automation Settings).


After your flow has been live for a bit, check in with users. Is it working as they expected? Are there any pain points? Any unexpected behavior? It’s always worth it to gather feedback because sometimes, what makes sense from a technical perspective doesn’t quite work from a user experience perspective. Being open to feedback and updating your flows based on real-world usage is what separates good builders from great ones.

Version Control and Change Management


Flows can have multiple versions, but only one version can be active at a time. When you make changes to an active flow, you’re creating a new version once it’s saved.


I would normally say to keep version descriptions up to date (as in note what changed in each version), but the new version comparison tool for Flow Builder makes this easier. If you need to roll back any changes you regret, it’s easy to activate an older version.

Final Thoughts: You’ve Made It!

If you’ve followed this series from Week 1 to Week 12, you’ve covered a lot of ground. From learning what Flow is, how to build them, how to test them, and now how to deploy them with confidence.

But here’s one thing to keep in mind about Flow: the learning never really stops. Every flow you build teaches you something new. Every mistake (and yes, you’ll make them, we all do) makes you a better builder. Every piece of feedback from users helps you design more thoughtfully. This continuous learning mindset doesn’t just apply to Flow, but even to Salesforce in general.

Flow is powerful, flexible, and sometimes frustrating. But it’s also one of the most impactful tools in your Salesforce toolkit. The fact that you’ve invested time in learning Flow shows that you care about building quality solutions. That mindset weighs more than any technical skill, and it is what will make you successful in the long run.

So with that I say… Go forth and build great flows! You’ve got this.

  1. What Is Salesforce Flow?
  2. The 4 Main Flow Types
  3. Flow Builder Overview and UI
  4. The Flow Elements
  5. Resources and Variables in Flow
  6. Decision Elements and Branching in Flow
  7. Why Loops, Collections, and the Transform Element Matter
  8. Screen, Record, and Schedule Triggered Flows
  9. Error Management and Fault Paths
  10. Debugging Flow
  11. Testing Flow
  12. Deploying Flow and Best Practices

The Author

Mariel Domingo

Mariel is a Technical Content Writer at Salesforce Ben.

Leave a Reply