Salesforce · · 40 min read

Flows in Salesforce

The definitive guide to Salesforce Flows — flow types, elements, resources, record-triggered flows, screen flows, scheduled flows, auto-launched flows, login flows, sub-flows, debugging, best practices, and hands-on projects.

Part 24: Flows in Salesforce

Welcome back to the Salesforce series. If there is one topic that deserves the label “must-master,” it is Flows. Salesforce Flows are the primary automation tool on the platform. They have replaced Workflow Rules and Process Builder, and they can handle everything from simple field updates to complex, multi-step business processes that span multiple objects. Whether you are an admin who has never written a line of code or a developer looking for a declarative alternative, Flows are the tool you will reach for most often.

This is Part 24 of the series, and it is intentionally one of the longest installments. We will cover every flow type, every category of element, debugging, best practices, and two complete hands-on projects. Take your time with this one.


What Are Flows?

A Flow is a declarative automation tool in Salesforce that allows you to collect data, make decisions, create or update records, call Apex code, send emails, and much more — all without writing code. Flows are built using a visual drag-and-drop interface called Flow Builder.

At its core, a flow is a series of connected elements that execute in a defined order. You can think of it like a flowchart: the process starts at one point, moves through decisions, loops, assignments, and data operations, and eventually finishes.

Benefits of Flows

  • No-code / low-code: Admins can build sophisticated automations without Apex.
  • Versatility: Flows can run on record changes, on a schedule, from a button click, during login, or be called from other automations.
  • UI capability: Screen Flows can present forms and interfaces to users, something no other declarative automation tool can do.
  • Consolidation: Flows replace Workflow Rules, Process Builder, and many uses of Apex triggers, giving you a single tool to learn and maintain.
  • Transaction control: Flows run within the Salesforce transaction, meaning they respect validation rules, triggers, and rollback behavior.
  • Debugging tools: Flow Builder includes a built-in debug mode that lets you step through a flow and inspect variable values at each stage.
  • Reusability: Sub-flows and invocable actions let you build modular, reusable pieces of automation.

Drawbacks of Flows

  • Complexity at scale: Very large flows with dozens of elements can become visually difficult to manage and debug.
  • Governor limits: Flows execute within Salesforce governor limits. Poorly designed flows can hit SOQL query limits, DML limits, or CPU time limits.
  • Learning curve: While Flows are “no-code,” the concepts of variables, loops, collections, and data operations can be challenging for beginners.
  • Version management: Each time you save a flow as a new version, older versions persist. Managing versions and ensuring the correct version is active requires attention.
  • Error handling: Without explicit fault paths, a flow that encounters an error will display a generic, unhelpful error message to the user.

How to Create a Flow

To create a new flow:

  1. Navigate to Setup and search for Flows in the Quick Find box.
  2. Click New Flow.
  3. Salesforce presents a selection screen where you choose the type of flow you want to build (Screen Flow, Record-Triggered Flow, Schedule-Triggered Flow, Autolaunched Flow, etc.).
  4. Select your flow type and click Create.
  5. You are now inside Flow Builder, the visual canvas where you design your flow.

The Flow Builder Interface

Flow Builder has several key areas:

  • Canvas: The central area where you drag and drop elements and connect them together.
  • Toolbox (left panel): Contains the elements and resources you can add to your flow. Elements are the building blocks (screens, decisions, loops, record operations). Resources are the data containers (variables, constants, formulas, text templates).
  • Button Bar (top): Contains Save, Save As, Activate, Debug, and Run buttons.
  • Properties Panel: When you select an element, its configuration options appear on the right or in a modal.

When you add elements to the canvas, you connect them with lines called connectors. The flow executes by following these connectors from one element to the next, starting from the Start element.


The Six Major Flow Types

Salesforce offers several flow types, each designed for specific use cases. Choosing the right type is critical.

1. Screen Flow

What it is: A flow that includes one or more screen elements where users interact with a form-like interface.

When to use it: When you need user input as part of the process. Examples include guided wizards, case creation forms, data entry tools, and approval request forms.

How it runs: A user clicks a button, a Quick Action, a link, or visits a Lightning page where the flow is embedded. The user steps through the screens, and the flow executes behind the scenes.

Key characteristics:

  • Runs in the context of the running user (respects their permissions).
  • Can be embedded in Lightning pages, Experience Cloud sites, utility bars, and more.
  • Supports navigation between screens (Next, Previous, Finish).
  • Can include input components like text fields, picklists, checkboxes, date pickers, file uploads, and custom Lightning Web Components.

2. Record-Triggered Flow

What it is: A flow that runs automatically when a record is created, updated, or deleted.

When to use it: When you need to automate actions in response to data changes. Examples include updating related records when an Opportunity closes, sending a notification when a high-priority Case is created, or validating data before a record is saved.

How it runs: The flow is triggered by a DML event (insert, update, delete) on a specific object. You configure the trigger conditions in the Start element.

Key characteristics:

  • Replaces Workflow Rules and Process Builder entirely.
  • Offers three timing options: Before Save (fast field updates on the triggering record), After Save (actions that affect other records or make callouts), and Run Asynchronously (for actions that can happen outside the immediate transaction).
  • Before-save flows are extremely efficient because they do not require a separate DML operation to update the triggering record.
  • Supports entry conditions so the flow only runs when specific criteria are met.
  • Can be configured to run on create only, update only, create or update, or delete.

3. Schedule-Triggered Flow

What it is: A flow that runs on a defined schedule (daily, weekly, or at a specific time).

When to use it: When you need batch processing or recurring tasks. Examples include sending weekly summary emails, closing stale opportunities, archiving old records, or running nightly data cleanup.

How it runs: Salesforce executes the flow at the scheduled time. The flow typically starts with a Get Records element to retrieve the records it needs to process.

Key characteristics:

  • Runs in system context (not tied to a specific user’s permissions by default).
  • Can be scheduled to run at a specific frequency.
  • Processes records in batches.
  • Great for maintenance tasks and periodic notifications.

4. Autolaunched Flow (No Trigger)

What it is: A flow that runs in the background without any user interaction and without a specific record trigger or schedule.

When to use it: When you want to build reusable automation that is called from other places — another flow, an Apex class, a Process Builder (legacy), a REST API call, or a platform event.

How it runs: It is invoked programmatically or from another automation. It does not have a trigger of its own.

Key characteristics:

  • No screens — runs entirely in the background.
  • Can accept input variables and return output variables.
  • Ideal for modular, reusable logic.
  • Can be called via the REST API, making it useful for integrations.
  • Runs in system context or user context depending on how it is invoked.

5. Platform Event-Triggered Flow

What it is: A flow that runs when a platform event message is published.

When to use it: When you need to respond to events from external systems or from other parts of Salesforce that publish platform events. Examples include processing incoming data from an integration or responding to a custom event in a complex architecture.

How it runs: When a platform event message matching the configured event type is published, the flow fires automatically.

Key characteristics:

  • Runs asynchronously.
  • Useful for event-driven architectures and integrations.
  • Processes one event message at a time.

6. Login Flow

What it is: A special type of screen flow that runs immediately after a user logs in to Salesforce.

When to use it: When you need to enforce actions during the login process. Examples include requiring users to accept updated terms of service, collecting additional profile information, routing users to a specific page based on their role, or enforcing multi-factor authentication steps.

How it runs: It is associated with a profile or a connected app. When a user with that profile logs in, the flow runs before the user reaches the home page.

Key characteristics:

  • Must be a Screen Flow (because it requires user interaction).
  • Associated with profiles in Setup under Login Flows.
  • Runs in the authenticated user’s context.
  • Can block login if the user does not complete the required steps (e.g., accepting terms).

Flow Resources

Resources are the data containers and tools that your flow uses to store, manipulate, and reference information. Understanding resources is essential to building effective flows.

Variables

Variables store a single value that can change as the flow executes. You define the data type (Text, Number, Currency, Boolean, Date, DateTime, Record, etc.) and optionally set a default value.

  • Single-value variables: Hold one value (e.g., a text string, a number, a date).
  • Record variables: Hold a single record with all its fields (e.g., one Account record).
  • Collection variables: Hold a list of values or records (e.g., a list of Contact records returned by a Get Records element).

To create a variable, open the Toolbox in Flow Builder, click New Resource, choose Variable, give it an API name, select the data type, and configure availability (input, output, or both) if needed.

Input/Output settings: If you mark a variable as “Available for input,” it can receive values from external sources when the flow is called. If you mark it as “Available for output,” its final value can be passed back to the calling process.

Constants

Constants store a value that does not change during the flow’s execution. Use constants for values you reference in multiple places and might need to update later — such as a department name, a threshold number, or a record type ID.

Formulas

Flow formulas work like formula fields but exist only within the flow. They evaluate dynamically each time they are referenced. You can use most of the same functions available in formula fields (TEXT, IF, ISBLANK, TODAY, NOW, etc.).

Text Templates

Text Templates let you compose rich text (HTML) or plain text that can include merge fields referencing flow variables. They are primarily used for email bodies, screen display text, or any place you need formatted output.

Choice Resources

Choices and Record Choices are used exclusively in Screen elements to present options to the user — in picklists, radio button groups, or multi-select checkboxes.

  • Choice: A single static option with a label and stored value.
  • Record Choice Set: Dynamically pulls options from Salesforce records (e.g., a picklist of all active Account names).
  • Picklist Choice Set: Pulls options directly from a picklist field’s metadata.

Stages

Stages allow you to define named steps in a flow to track progress. They are useful in Screen Flows where you want to show users a progress indicator across multiple screens.


Flow Interaction Elements Overview

Interaction elements are the components users see and interact with in Screen Flows. They live inside Screen elements.

Screen Element

The Screen element is the container that holds input and display components. When the flow reaches a Screen element, it pauses and presents the screen to the user. The user fills in fields, makes selections, and clicks Next, Previous, or Finish.

Inside a screen, you can add:

  • Text Input: A single-line text field.
  • Long Text Area: A multi-line text field.
  • Number Input: For numeric values.
  • Currency Input: For money values.
  • Date and Date/Time Inputs: For date selection.
  • Checkbox: A single true/false toggle.
  • Checkbox Group: Multiple checkboxes for multi-select.
  • Radio Buttons: Single-select options.
  • Picklist: A dropdown selection, often populated by a Choice resource.
  • Toggle: A visual on/off switch.
  • File Upload: Allows users to attach files.
  • Display Text: Read-only rich text for instructions or information.
  • Display Image: Show images on the screen.
  • Section: Groups components visually into columns.
  • Lookup: A record lookup field that lets users search for and select a record.
  • Custom Lightning Web Components: You can embed LWCs for advanced UI needs.

Screen Navigation

Screens support navigation buttons: Next (advance to the next screen or element), Previous (go back to the prior screen), Finish (complete the flow), and Pause (let the user save progress and return later, if enabled).

You can control which buttons appear, customize their labels, and define what happens when the flow finishes (redirect to a URL, show a confirmation screen, etc.).


Flow Logic Elements Overview

Logic elements control the path the flow takes based on conditions.

Decision Element

The Decision element evaluates one or more conditions and routes the flow down different paths — similar to an if/else statement in code.

When you add a Decision, you define outcomes. Each outcome has a label and a set of conditions. The flow evaluates outcomes from top to bottom and follows the first outcome whose conditions are true. There is always a Default Outcome that the flow follows if none of the defined conditions are met.

Example: You have a flow processing leads. You add a Decision with three outcomes:

  • Outcome 1: Lead Source equals “Web” — route to a web-specific path.
  • Outcome 2: Lead Source equals “Referral” — route to a referral path.
  • Default Outcome: Handle all other leads.

Loop Element

The Loop element iterates over a collection variable, processing one item at a time. On each iteration, the current item is stored in a loop variable that you can reference in the elements inside the loop.

Important rules for loops:

  • You cannot put a Screen element inside a loop.
  • Avoid DML operations (Create, Update, Delete) inside loops — this is a major performance anti-pattern. Instead, build a collection inside the loop and perform a single DML operation after the loop completes.
  • The loop processes items in the order they appear in the collection.

Assignment Element

The Assignment element sets or modifies variable values. You select a variable, choose an operator (Equals, Add, Subtract, Add Item for collections), and specify the value.

Common uses:

  • Setting a variable to a value retrieved from a record.
  • Incrementing a counter.
  • Adding items to a collection variable inside a loop.
  • Concatenating strings.
  • Setting a Boolean flag.

Wait Element (Autolaunched Flows Only)

The Wait element pauses the flow until a specified event occurs — either a specific date/time is reached or a platform event is received. The Wait element is available only in certain flow types (not Screen Flows).


Flow Data Elements Overview

Data elements interact with the Salesforce database.

Get Records

Retrieves records from a Salesforce object based on filter criteria. You specify the object, the filter conditions, the fields to retrieve, how to sort the results, and how many records to return.

Configuration options:

  • How Many Records to Store: “Only the first record” stores the result in a record variable. “All records” stores them in a collection variable.
  • Filter Conditions: Define which records to retrieve (e.g., Account Name equals {!varAccountName}).
  • Sort Order: Sort by a field in ascending or descending order.

Tip: If a Get Records element finds no matching records, the variable will be null. Always handle this scenario with a Decision element or a null check.

Create Records

Creates one or more new records in Salesforce. You can either map individual field values or use a record variable or collection variable to create records.

  • Single record: Set field values manually within the element.
  • Multiple records: Pass a record collection variable. The flow creates all records in the collection with a single DML operation.

After a successful create, the record ID is stored in a variable that you can reference later in the flow.

Update Records

Updates existing records. You have two approaches:

  • Filter and update: Specify the object, filter criteria, and the field values to change. The flow finds matching records and updates them.
  • Use a record or collection variable: If you already have a record or collection variable (from a Get Records element), you can modify fields using Assignment elements and then pass the variable to Update Records.

Delete Records

Deletes records matching specified filter criteria. You define the object and the conditions, and the flow deletes all matching records.

Use with caution: Deleted records go to the Recycle Bin, but bulk deletions in flows can be difficult to reverse.


Create a Record-Triggered Flow

Let us walk through building a record-triggered flow step by step.

Scenario: When an Opportunity’s Stage changes to “Closed Won,” automatically update the related Account’s Description field to include the text “Has closed-won opportunity” and the close date.

Step-by-Step

  1. Go to Setup > Flows > New Flow.
  2. Select Record-Triggered Flow and click Create.
  3. Configure the Start element:
    • Object: Opportunity
    • Trigger the Flow When: A record is updated
    • Entry Conditions: Set condition — Stage Equals “Closed Won”
    • Under “When to Run the Flow for Updated Records,” select Only when a record is updated to meet the condition (this ensures it runs only when the stage transitions to Closed Won, not every time a Closed Won Opportunity is edited).
    • Optimize the Flow for: Actions and Related Records (After Save).
  4. Add a Get Records element (to retrieve the related Account):
    • Label: “Get Related Account”
    • Object: Account
    • Filter: Id Equals {!$Record.AccountId}
    • How Many Records: Only the first record
    • Store in: Automatically stored as “Get_Related_Account” record variable.
  5. Add a Decision element (to check the Account was found):
    • Label: “Account Found?”
    • Outcome 1: “Yes” — Condition: {!Get_Related_Account} Is Null equals {!$GlobalConstant.False}
    • Default Outcome: “No Account” — no further action.
  6. On the “Yes” path, add an Update Records element:
    • Label: “Update Account Description”
    • How to Find Records: Use the record variable {!Get_Related_Account}
    • Actually, use the filter approach: Object = Account, Filter by Id = {!$Record.AccountId}
    • Set Field Values: Description = “Has closed-won opportunity as of ” & TEXT({!$Record.CloseDate})
  7. Save the flow with a name like “Opportunity Closed Won - Update Account.”
  8. Activate the flow.

Before-Save vs. After-Save

If you only need to update fields on the triggering record itself, use a Before Save flow. Before-save flows run before the record is committed to the database, so field updates happen without an extra DML operation. This is faster and more efficient.

For our scenario, we are updating a different object (Account), so we must use After Save.


Create a Screen Flow

Scenario: Build a screen flow that lets support agents quickly log a new Case with pre-selected defaults and some auto-populated fields.

Step-by-Step

  1. Go to Setup > Flows > New Flow.
  2. Select Screen Flow and click Create.
  3. Add a Screen element (the input form):
    • Label: “Case Information”
    • Add these components to the screen:
      • Text Input: Label = “Subject”, Required = True. API Name = “Subject_Input”.
      • Long Text Area: Label = “Description”. API Name = “Description_Input”.
      • Picklist: Label = “Priority”. Use a Picklist Choice Set resource tied to the Case.Priority field. API Name = “Priority_Picklist”.
      • Picklist: Label = “Case Origin”. Use a Picklist Choice Set tied to Case.Origin. API Name = “Origin_Picklist”.
      • Lookup: Label = “Account”. Object = Account. API Name = “Account_Lookup”.
    • Configure the Footer: Show the “Next” or “Finish” button.
  4. Add a Create Records element:
    • Label: “Create Case”
    • Object: Case
    • Set Field Values:
      • Subject = {!Subject_Input}
      • Description = {!Description_Input}
      • Priority = {!Priority_Picklist}
      • Origin = {!Origin_Picklist}
      • AccountId = {!Account_Lookup.recordId}
      • Status = “New” (hardcoded default)
  5. Add a second Screen element (confirmation):
    • Label: “Confirmation”
    • Add a Display Text component: “Case has been created successfully. Case Number: {!Create_Case}” (referencing the output ID from the Create Records element).
    • Hide the Previous button. Show only the Finish button.
  6. Save the flow as “Quick Case Creation.”
  7. Activate the flow.

Deploying a Screen Flow

Screen Flows can be placed in many locations:

  • Lightning Record Pages: Add the flow component to any record page using the Lightning App Builder.
  • Lightning App Pages and Home Pages: Embed the flow on custom app pages.
  • Quick Actions: Create a flow action and add it to the page layout.
  • Experience Cloud Sites: Add the flow component to community pages.
  • Utility Bar: Place the flow in the utility bar for quick access across the app.
  • Custom Buttons and Links: Link to the flow’s URL.

Create a Schedule-Triggered Flow

Scenario: Every Monday at 8:00 AM, find all open Opportunities with a Close Date in the past and update their Stage to “Closed Lost.”

Step-by-Step

  1. Go to Setup > Flows > New Flow.
  2. Select Schedule-Triggered Flow and click Create.
  3. Configure the Start element:
    • Set the schedule: Frequency = Weekly, Day = Monday, Time = 8:00 AM.
  4. Add a Get Records element:
    • Label: “Get Stale Opportunities”
    • Object: Opportunity
    • Filter Conditions:
      • IsClosed Equals {!$GlobalConstant.False}
      • CloseDate Less Than {!$Flow.CurrentDate}
    • How Many Records: All records
    • Store in: Collection variable (auto-created).
  5. Add a Decision element:
    • Label: “Any Stale Opportunities?”
    • Outcome: “Yes” — Condition: {!Get_Stale_Opportunities} Is Null equals {!$GlobalConstant.False}
    • Default: “No Records” — end.
  6. On the “Yes” path, add a Loop element:
    • Label: “Loop Through Opportunities”
    • Collection Variable: {!Get_Stale_Opportunities}
    • Loop variable will hold the current Opportunity record on each iteration.
  7. Inside the loop, add an Assignment element:
    • Label: “Set Stage to Closed Lost”
    • Variable: {!Loop_Through_Opportunities.StageName}
    • Operator: Equals
    • Value: “Closed Lost”
    • Then add another Assignment to add the current record to a new collection variable called “Opps_To_Update”:
      • Variable: {!Opps_To_Update}
      • Operator: Add Item
      • Value: {!Loop_Through_Opportunities}
  8. After the loop (on the “After Last” connector), add an Update Records element:
    • Label: “Update Opportunities”
    • Use the record collection: {!Opps_To_Update}
  9. Save and Activate.

Key point: Notice how we build the collection inside the loop and perform the update after the loop. This is a critical best practice — performing DML inside a loop will hit governor limits quickly.


Create an Autolaunched Flow

Scenario: Build a reusable flow that accepts a Contact ID as input, looks up the Contact, and returns the Contact’s full name and associated Account name as output variables.

Step-by-Step

  1. Go to Setup > Flows > New Flow.

  2. Select Autolaunched Flow (No Trigger) and click Create.

  3. Create an input variable:

    • Open the Toolbox, click New Resource > Variable.
    • API Name: “varContactId”
    • Data Type: Text
    • Available for Input: Checked
  4. Create output variables:

    • “varFullName” — Text, Available for Output: Checked.
    • “varAccountName” — Text, Available for Output: Checked.
  5. Add a Get Records element:

    • Label: “Get Contact”
    • Object: Contact
    • Filter: Id Equals {!varContactId}
    • How Many Records: Only the first record
  6. Add a Decision element:

    • “Contact Found?” — Check that the result is not null.
  7. On the “Found” path, add Assignment elements:

    • Set {!varFullName} = {!Get_Contact.FirstName} & ” ” & {!Get_Contact.LastName}
    • Set {!varAccountName} = {!Get_Contact.Account.Name}

    (Note: To reference the related Account name, you may need a separate Get Records on the Account object using the Contact’s AccountId, depending on how you configured the Get Records element.)

  8. Save and Activate.

This flow can now be called from other flows (as a sub-flow), from Apex, or from the REST API.


How to Create a Login Flow

Login Flows intercept the login process and require users to complete specific steps before reaching Salesforce.

Step-by-Step

  1. Build a Screen Flow that contains the screens you want the user to see at login. For example, a screen displaying updated Terms of Service with a checkbox the user must select to acknowledge acceptance.
  2. Save and Activate the Screen Flow.
  3. Navigate to Setup > Login Flows.
  4. Click New.
  5. Select the flow you created from the lookup.
  6. Assign it to one or more Profiles.
  7. Save.

Now, when users with those profiles log in, they will be routed through the flow before they reach the Salesforce home page.

Considerations

  • The flow must be a Screen Flow.
  • Keep login flows lightweight — users should not be stuck in a long process every time they log in. Use variables or custom settings to track whether the user has already completed the flow (e.g., a custom field on the User object that records the last accepted Terms of Service version).
  • If the flow encounters an error, the user may be unable to log in. Test thoroughly before deploying.
  • Login flows have access to a limited set of system variables and cannot perform all the same operations as a normal Screen Flow.

When to Create a Sub-Flow

A sub-flow is simply an Autolaunched Flow or Screen Flow that is invoked from within another flow using the Subflow element.

When to Use Sub-Flows

  • Reusable logic: If the same sequence of steps appears in multiple flows, extract it into a sub-flow and call it from each parent flow.
  • Modular design: Break large, complex flows into smaller, manageable pieces. Each sub-flow handles one responsibility.
  • Team collaboration: Different admins can work on different sub-flows without conflicting in a single large flow.
  • Maintainability: When business logic changes, you update it in one sub-flow rather than in every flow that contains that logic.

How to Use

  1. Build and activate the sub-flow (an Autolaunched Flow with input/output variables).
  2. In the parent flow, add a Subflow element from the toolbox.
  3. Select the sub-flow by name.
  4. Map input values from the parent flow’s variables to the sub-flow’s input variables.
  5. Map the sub-flow’s output variables back to variables in the parent flow.

Example: You have five different flows that all need to calculate a discount percentage based on account tier. Build one sub-flow called “Calculate Discount” that accepts an Account ID as input and returns the discount percentage as output. All five parent flows call this single sub-flow.


Flow Fault Paths

When an element in a flow encounters an error at runtime — for example, a Create Records element fails because of a validation rule, or a Get Records element encounters a permissions issue — the flow follows a fault path if one is defined.

What Happens Without a Fault Path

If no fault path is defined and an error occurs:

  • In a Screen Flow, the user sees a generic, unhelpful error message: “An unhandled fault has occurred in this flow.”
  • In a Record-Triggered or Autolaunched Flow, the error is logged, and the triggering transaction may be rolled back.

How to Add a Fault Path

  1. Select the element that might fail (typically data elements like Create, Update, or Delete Records).
  2. You will see a Fault connector available on the element.
  3. Drag the Fault connector to a new element — usually a Screen element (in Screen Flows) that displays a user-friendly error message, or an action that logs the error.
  4. Inside the fault path, you can reference the {!$Flow.FaultMessage} system variable to get the specific error message.

Best Practices for Fault Paths

  • Add fault paths to every data element in Screen Flows so users see clear error messages.
  • In background flows, add fault paths that create a log record (e.g., a custom “Flow Error Log” object) or send an email to an admin.
  • Use the {!$Flow.FaultMessage} variable to capture what went wrong.
  • Keep fault path actions simple — if a fault path itself errors, you lose visibility into the original problem.

Debugging a Flow

Flow Builder includes a built-in debugger that is indispensable for testing and troubleshooting.

How to Debug

  1. Open the flow in Flow Builder.
  2. Click the Debug button in the top button bar.
  3. If the flow requires input variables or a triggering record, you will be prompted to provide them. For record-triggered flows, you can select a specific record to simulate the trigger.
  4. Click Run.
  5. The debugger executes the flow and displays the Debug Details panel, showing:
    • Each element that was executed, in order.
    • The values of all variables at each step.
    • Which path was taken at each Decision element.
    • Any errors encountered.

Debug Tips

  • Use debug logs alongside flow debugging: If your flow calls Apex actions or triggers, the Apex debug log provides additional context.
  • Test with different records: Run the debugger with records that match different conditions to test all Decision paths.
  • Check for null values: Many flow errors stem from null variables. The debugger makes it easy to spot where a variable unexpectedly has no value.
  • Test fault paths: Deliberately provide inputs that will cause errors (e.g., a record ID that does not exist) to verify your fault paths work correctly.
  • Roll back mode: The debugger supports a “Roll Back” option that executes the flow but does not commit changes to the database. This is useful for testing in production without affecting real data.

Emailing in Flows

Flows can send emails using the Send Email action (available as a Core Action in the flow toolbox).

Configuring the Send Email Action

  1. Add an Action element to your flow.
  2. Search for and select Send Email.
  3. Configure the email:
    • Recipient Email Addresses: A comma-separated list or a text variable containing email addresses.
    • Subject: The email subject line (can include merge fields from flow variables).
    • Body: The email body. You can use a Text Template resource for rich formatting with merge fields.
    • Sender Type: Choose between the running user’s email or the org-wide email address.
    • Related Record ID: Optionally associate the email with a record so it appears in that record’s Activity History.

Using Email Alerts vs. Send Email

  • Send Email action: Flexible, lets you compose the email entirely within the flow. Best for dynamic, flow-specific emails.
  • Email Alert action: Uses a pre-configured email alert (which references an email template). Best when you want to reuse an existing email template or when non-admins manage the template content.

Both approaches can be used in any flow type, though screen flows typically send emails after the user completes the screens.


The Flow Trigger Explorer

The Flow Trigger Explorer is a tool in Setup that provides a consolidated view of all record-triggered flows on a given object.

How to Access It

  1. Go to Setup > Flows.
  2. Click Flow Trigger Explorer (or access it from the object’s record-triggered flow list).
  3. Select an object (e.g., Opportunity).

What It Shows

  • All record-triggered flows for that object, organized by trigger timing (Before Save, After Save, Async).
  • The order in which flows execute.
  • Whether each flow is active or inactive.

Why It Matters

When multiple record-triggered flows exist on the same object, the order of execution can matter. The Flow Trigger Explorer lets you:

  • See all automations in one place instead of hunting through individual flows.
  • Reorder flow execution when necessary (you can set the order for flows within the same trigger timing).
  • Identify conflicts or redundant automations.
  • Quickly check which flows are active.

Automation Lightning App

Salesforce provides a dedicated Automation Lightning app (sometimes called the Automation Home) that serves as a central hub for managing all your automations.

Features

  • Dashboard view: See counts of active flows, paused flow interviews, and flow errors.
  • Flow list: View all flows in the org with their type, status, and last modified date.
  • Migration tools: Tools to help migrate from Workflow Rules and Process Builder to Flows.
  • Error tracking: Review recent flow errors with details about what went wrong and which records were affected.
  • Usage metrics: See how often flows run and identify high-traffic automations.

To access it, open the App Launcher and search for “Automation.”


Flow Best Practices

These are the most important practices for building reliable, scalable, and maintainable flows.

1. Bulkify Your Flows

Never perform DML operations (Create, Update, Delete) or SOQL queries (Get Records) inside a loop. Instead, collect records in a collection variable inside the loop and perform the data operation once after the loop ends. This prevents governor limit violations.

2. Use Before-Save Flows When Possible

If you only need to update fields on the triggering record, use a Before-Save Record-Triggered Flow. It runs before the record is committed, so it does not consume an extra DML operation. This is faster and more efficient than After-Save flows for simple field updates.

3. Add Fault Paths

Every data element (Create, Update, Delete, Get Records) should have a fault path that gracefully handles errors. In Screen Flows, show the user a meaningful error message. In background flows, log the error for admin review.

4. Use Naming Conventions

  • Name flow elements clearly: “Get Related Account,” “Decision: Is VIP Customer,” “Update Contact Status.”
  • Use consistent prefixes for variables: “var” for variables, “col” for collections, “rec” for single record variables, “const” for constants.
  • Name flows themselves descriptively: “Opportunity - Closed Won - Update Account” is better than “My Flow 3.”

5. Use Entry Conditions

For record-triggered flows, always set entry conditions to limit when the flow runs. A flow that fires on every record update (even when irrelevant fields change) wastes processing time and can cause unexpected side effects.

6. Handle Null Values

Always check whether a Get Records element returned a result before trying to use it. A null record variable will cause errors if you try to reference its fields. Use a Decision element to check for null.

7. Limit Flows Per Object

Avoid having too many record-triggered flows on a single object. Each flow adds processing overhead. Consolidate related logic into fewer flows when practical.

8. Document Your Flows

Use the Description field on every element and on the flow itself. Future administrators (including your future self) will thank you. Add comments explaining why decisions were made, not just what the flow does.

9. Test in a Sandbox First

Always build and test flows in a sandbox before deploying to production. Use the debugger, test with various data scenarios, and verify that governor limits are not approached.

10. Version Management

When updating an existing flow, save a new version rather than deactivating and creating a new flow. This preserves the history and allows you to roll back if needed.

11. Use Sub-Flows for Reusability

If you find yourself building the same logic in multiple flows, extract it into a sub-flow. This follows the DRY (Don’t Repeat Yourself) principle and makes maintenance easier.

12. Avoid Recursive Flows

Be careful when a record-triggered flow updates a record that triggers another flow, which updates another record, and so on. Salesforce has some built-in protection against infinite loops, but recursive flows can still cause unexpected behavior. Use entry conditions and the “Only when a record is updated to meet the condition” setting to prevent unnecessary re-execution.


Section Notes

  • Flows are the single most important declarative automation tool in Salesforce. Investing time in mastering them pays dividends across every admin and developer role.
  • Salesforce is actively retiring Workflow Rules and Process Builder. All new automation should be built with Flows, and existing automations should be migrated when practical.
  • The Flow Builder interface receives regular updates from Salesforce. New elements, new screen components, and new debugging capabilities appear with each release.
  • Flow interviews (running instances of flows) can be paused and resumed. This is useful for Screen Flows where the user might need to gather information before completing the process.
  • Flows respect sharing rules, field-level security, and object permissions depending on the context they run in. Be mindful of the “Run flow as” system context versus user context setting.
  • When building complex flows, sketch the logic on paper or in a diagramming tool before opening Flow Builder. Planning ahead prevents rework.
  • Record-triggered flows that run “Before Save” cannot access related records or perform DML on other objects. They can only modify fields on the triggering record.
  • The maximum number of executed elements per flow interview is 2,000 by default. Extremely complex flows or flows processing large datasets can hit this limit.
  • Always consider what happens if your flow runs on a bulk data load. If someone imports 10,000 records via Data Loader, your record-triggered flow runs for each record. Make sure it is efficient.

PROJECT: Create a Screen Flow for Users to Create a Case in an Experience Cloud Site

This project walks you through building a full Case creation Screen Flow designed for external users in an Experience Cloud (Community) site.

Business Requirement

External customers who log in to your Experience Cloud site should be able to create support Cases directly from the portal. The flow should collect the case details, associate the case with the customer’s Account, and display a confirmation message with the Case Number.

Step 1: Plan the Flow

The flow will have three screens:

  1. Case Details Screen: Collects subject, description, priority, and category.
  2. Review Screen: Displays the entered information for the user to confirm before submitting.
  3. Confirmation Screen: Shows success message and Case Number.

Behind the scenes, the flow will:

  • Automatically associate the Case with the running user’s Account (for community users, this is their related Account).
  • Set default values for Status and Origin.
  • Handle errors gracefully.

Step 2: Create the Flow

  1. Go to Setup > Flows > New Flow > Screen Flow > Create.

Step 3: Create Resources

Create the following resources in the Toolbox:

  • Variable: “varAccountId” — Type: Text. (We will populate this from the running user’s Contact record.)
  • Variable: “varCaseNumber” — Type: Text. (To store the created Case Number for display.)
  • Record Variable: “recCreatedCase” — Type: Record, Object: Case. (Optional, for referencing the created case.)
  • Picklist Choice Set: “pcsCategory” — Object: Case, Field: Type (or your custom category field). This dynamically populates case category options.
  • Picklist Choice Set: “pcsPriority” — Object: Case, Field: Priority.
  • Text Template: “ttReviewSummary” — Contains HTML displaying the user’s entries for review.
  • Text Template: “ttConfirmation” — Contains the success message.

Step 4: Get the User’s Account

Add a Get Records element as the first element:

  • Label: “Get Current User Contact”
  • Object: Contact
  • Filter Conditions:
    • User Account (the related User field) — depending on your community setup, you might filter by the running user’s ID. A common approach: use the {!$User.Id} to look up the related Contact record.
    • Alternatively, if your community users have a ContactId: filter Contact.Id Equals {!$User.ContactId} (available via a formula resource that references $User.ContactId).
  • How Many Records: Only the first record.
  • Store fields: AccountId.

Add an Assignment element:

  • Set {!varAccountId} = {!Get_Current_User_Contact.AccountId}.

Step 5: Build the Case Details Screen

Add a Screen element:

  • Label: “Case Details”
  • Components:
    • Display Text: “Please provide the details for your support request.”
    • Text Input: Label = “Subject”, API Name = “inputSubject”, Required = True.
    • Long Text Area: Label = “Description”, API Name = “inputDescription”, Required = True.
    • Picklist: Label = “Category”, API Name = “inputCategory”, Picklist Choice Set = {!pcsCategory}.
    • Picklist: Label = “Priority”, API Name = “inputPriority”, Picklist Choice Set = {!pcsPriority}, Default Value = “Medium”.
  • Footer: Show Next button.

Step 6: Build the Review Screen

Create the Text Template resource “ttReviewSummary”:

<p><strong>Subject:</strong> {!inputSubject}</p>
<p><strong>Description:</strong> {!inputDescription}</p>
<p><strong>Category:</strong> {!inputCategory}</p>
<p><strong>Priority:</strong> {!inputPriority}</p>
<p>Click <strong>Next</strong> to submit your case or <strong>Previous</strong> to make changes.</p>

Add a Screen element:

  • Label: “Review Your Case”
  • Components:
    • Display Text: Use the text template {!ttReviewSummary}.
  • Footer: Show Next and Previous buttons.

Step 7: Create the Case Record

Add a Create Records element:

  • Label: “Create Case Record”
  • Object: Case
  • Set Field Values:
    • Subject = {!inputSubject}
    • Description = {!inputDescription}
    • Type = {!inputCategory}
    • Priority = {!inputPriority}
    • AccountId = {!varAccountId}
    • Status = “New”
    • Origin = “Web”
  • Store the output Case ID.

Step 8: Get the Case Number

Add a Get Records element:

  • Label: “Get Created Case”
  • Object: Case
  • Filter: Id = {!Create_Case_Record} (the stored ID from the previous element)
  • How Many Records: Only the first record
  • Store the CaseNumber field.

Add an Assignment:

  • {!varCaseNumber} = {!Get_Created_Case.CaseNumber}

Step 9: Build the Confirmation Screen

Create the Text Template “ttConfirmation”:

<p style="font-size:18px; color:green;">Your case has been submitted successfully.</p>
<p><strong>Case Number:</strong> {!varCaseNumber}</p>
<p>Our support team will review your request and get back to you shortly.</p>

Add a Screen element:

  • Label: “Confirmation”
  • Components:
    • Display Text: Use {!ttConfirmation}.
  • Footer: Show only the Finish button. Hide Previous.

Step 10: Add a Fault Path

Select the “Create Case Record” element and drag the Fault connector to a new Screen element:

  • Label: “Error Screen”
  • Components:
    • Display Text: “We’re sorry, but an error occurred while creating your case. Please try again or contact support directly. Error details: {!$Flow.FaultMessage}”
  • Footer: Show only Finish.

Step 11: Save, Activate, and Deploy

  1. Save the flow as “Experience Cloud - Create Case.”
  2. Activate the flow.
  3. In Experience Builder for your community site, navigate to the page where you want the flow to appear.
  4. Drag the Flow component onto the page.
  5. Select “Experience Cloud - Create Case” from the flow picker.
  6. Publish the site.

External users can now create support cases directly from the portal with a guided, user-friendly experience.


PROJECT: Create a Record-Triggered Flow That Creates Tasks for Certain Opportunities

This project builds a record-triggered flow that automatically creates follow-up tasks when specific types of Opportunities are created.

Business Requirement

When a new Opportunity is created with an Amount greater than $50,000 and a Stage of “Qualification,” the system should automatically create two Tasks assigned to the Opportunity Owner:

  1. “Schedule executive review meeting” — Due in 3 days.
  2. “Prepare proposal document” — Due in 7 days.

Step 1: Create the Flow

  1. Go to Setup > Flows > New Flow.
  2. Select Record-Triggered Flow and click Create.

Step 2: Configure the Start Element

  • Object: Opportunity
  • Trigger the Flow When: A record is created
  • Entry Conditions (All conditions must be met):
    • Amount Greater Than 50000
    • StageName Equals “Qualification”
  • Optimize the Flow for: Actions and Related Records (After Save — because we are creating related Task records).

Step 3: Create Collection Variable for Tasks

In the Toolbox, create a new resource:

  • Type: Variable
  • API Name: “colTasksToCreate”
  • Data Type: Record
  • Object: Task
  • Allow Multiple Values (Collection): Checked

Step 4: Create Record Variables for Each Task

Create two Record Variables:

Record Variable 1:

  • API Name: “recTask1_ExecReview”
  • Data Type: Record
  • Object: Task

Record Variable 2:

  • API Name: “recTask2_Proposal”
  • Data Type: Record
  • Object: Task

Step 5: Create a Formula for Due Dates

Create two Formula resources:

Formula 1:

  • API Name: “fmlDueDate3Days”
  • Data Type: Date
  • Formula: {!$Flow.CurrentDate} + 3

Formula 2:

  • API Name: “fmlDueDate7Days”
  • Data Type: Date
  • Formula: {!$Flow.CurrentDate} + 7

Step 6: Build Assignment Elements

Assignment 1 — “Set Task 1 Fields”:

  • {!recTask1_ExecReview.Subject} Equals “Schedule executive review meeting”
  • {!recTask1_ExecReview.ActivityDate} Equals {!fmlDueDate3Days}
  • {!recTask1_ExecReview.OwnerId} Equals {!$Record.OwnerId}
  • {!recTask1_ExecReview.WhatId} Equals {!$Record.Id}
  • {!recTask1_ExecReview.Priority} Equals “High”
  • {!recTask1_ExecReview.Status} Equals “Not Started”
  • {!recTask1_ExecReview.Description} Equals “High-value opportunity requires executive review. Amount: $” & TEXT({!$Record.Amount})

Assignment 2 — “Set Task 2 Fields”:

  • {!recTask2_Proposal.Subject} Equals “Prepare proposal document”
  • {!recTask2_Proposal.ActivityDate} Equals {!fmlDueDate7Days}
  • {!recTask2_Proposal.OwnerId} Equals {!$Record.OwnerId}
  • {!recTask2_Proposal.WhatId} Equals {!$Record.Id}
  • {!recTask2_Proposal.Priority} Equals “Normal”
  • {!recTask2_Proposal.Status} Equals “Not Started”
  • {!recTask2_Proposal.Description} Equals “Prepare a detailed proposal for opportunity: ” & {!$Record.Name}

Assignment 3 — “Add Tasks to Collection”:

  • {!colTasksToCreate} Add Item {!recTask1_ExecReview}
  • {!colTasksToCreate} Add Item {!recTask2_Proposal}

Step 7: Create the Task Records

Add a Create Records element:

  • Label: “Create Follow-Up Tasks”
  • How to Create: Use a record collection — {!colTasksToCreate}

Step 8: Add a Fault Path

Drag the Fault connector from “Create Follow-Up Tasks” to a new Action element:

  • Use the Send Email action.
  • Recipient: Your admin email or a distribution list.
  • Subject: “Flow Error: Opportunity Task Creation Failed”
  • Body: “The flow failed to create follow-up tasks for Opportunity {!$Record.Name} (ID: {!$Record.Id}). Error: {!$Flow.FaultMessage}“

Step 9: Connect, Save, and Activate

  1. Connect all elements in order: Start > Set Task 1 Fields > Set Task 2 Fields > Add Tasks to Collection > Create Follow-Up Tasks.
  2. Ensure the fault path is connected from Create Follow-Up Tasks to the Send Email action.
  3. Save the flow as “Opportunity - High Value - Create Follow-Up Tasks.”
  4. Activate the flow.

Step 10: Test

  1. Create a new Opportunity with Amount = $75,000 and Stage = “Qualification.”
  2. After saving, navigate to the Opportunity’s Activity timeline.
  3. Verify two Tasks were created:
    • “Schedule executive review meeting” — Due in 3 days, Priority = High.
    • “Prepare proposal document” — Due in 7 days, Priority = Normal.
  4. Test the negative scenario: Create an Opportunity with Amount = $30,000. Verify no Tasks are created.
  5. Test another negative scenario: Create an Opportunity with Amount = $60,000 but Stage = “Prospecting.” Verify no Tasks are created.

Why This Pattern Matters

This project demonstrates several important patterns:

  • Using record variables and collection variables to build multiple records efficiently.
  • Performing a single Create Records operation instead of two separate ones (bulkification).
  • Using formula resources for calculated values like due dates.
  • Adding fault paths with email notifications for background flow errors.
  • Setting precise entry conditions so the flow only fires when truly needed.

What’s Next

Flows are the present and the future of Salesforce automation. Every scenario that once required Workflow Rules or Process Builder — and many that once required Apex code — can now be handled with Flows. In the next part, Part 25: Retired Automation Processes, we will look at the tools that Flows have replaced: Workflow Rules and Process Builder. Understanding what they were, why they are being retired, and how to migrate existing automations to Flows will complete your automation knowledge.

See you in the next one.