{"id":19926,"date":"2026-08-11T12:20:53","date_gmt":"2026-08-11T12:20:53","guid":{"rendered":"https:\/\/dianapps.com\/blog\/?p=19926"},"modified":"2026-08-11T12:30:25","modified_gmt":"2026-08-11T12:30:25","slug":"the-ultimate-guide-to-salesforce-flow","status":"publish","type":"post","link":"https:\/\/dianapps.com\/blog\/the-ultimate-guide-to-salesforce-flow\/","title":{"rendered":"The Ultimate Guide to Salesforce Flow: Types, Best Practices and Error Handling"},"content":{"rendered":"<p><span style=\"font-weight: 400;\">Salesforce Flow is now the primary way to automate business processes in Salesforce without writing Apex. From updating records and routing work to guiding users through multi-step processes, Flow can handle a wide range of automation needs across a Salesforce org.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">But knowing the different types of Salesforce Flow is only the starting point. The real challenge is building flows that perform well, handle errors properly, respect security requirements, and continue working as your data volume and automation landscape grow.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">In this guide, we\u2019ll cover the four main Salesforce Flow types, when to use before-save vs. after-save flows, how to build record-triggered flows, how fault paths and error handling work, the limits that can affect performance, run-context security, testing, migration from Process Builder and Workflow Rules, and practical best practices.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">For more complex automation requirements, <\/span><a href=\"https:\/\/dianapps.com\/salesforce-development-services\"><span style=\"font-weight: 400;\">Salesforce development services<\/span><\/a><span style=\"font-weight: 400;\"> from a reliable partner can also help businesses design, build, integrate, test, and optimize Flow-based solutions as part of a broader Salesforce environment.<\/span><\/p>\n<blockquote><p><b>TL;DR<\/b><span style=\"font-weight: 400;\">: Four main types: <\/span><b>Screen<\/b><span style=\"font-weight: 400;\"> (a user launches it), <\/span><b>Record-Triggered<\/b><span style=\"font-weight: 400;\"> (a record changes), <\/span><b>Schedule-Triggered<\/b><span style=\"font-weight: 400;\"> (a clock), <\/span><b>Autolaunched<\/b><span style=\"font-weight: 400;\"> (something else calls it). Use <\/span><b>before-save<\/b><span style=\"font-weight: 400;\"> for same-record field updates &#8211; it\u2019s roughly 10\u00d7 faster. Put a <\/span><b>fault path<\/b><span style=\"font-weight: 400;\"> on every element that touches data. Record-triggered and scheduled flows run in <\/span><b>system mode<\/b><span style=\"font-weight: 400;\">, which ignores the running user\u2019s permissions, and the old 2,000-element limit was removed in API v57, despite what most guides still say.<\/span><\/p><\/blockquote>\n<h2><b>What Is Salesforce Flow?<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">Salesforce Flow is the platform\u2019s declarative automation tool where you build business logic visually in Flow Builder rather than writing Apex. It has replaced both Workflow Rules and Process Builder, and it now handles the large majority of automation most orgs need.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">For businesses looking to streamline complex processes, <\/span><span style=\"font-weight: 400;\">Salesforce development services<\/span><span style=\"font-weight: 400;\"> can help design, build, and optimize Flow-based automation while ensuring it works reliably with the rest of the Salesforce ecosystem.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">It matters more than it used to for a structural reason: Workflow Rules and Process Builder are retired, so Flow isn\u2019t one option among several anymore. It\u2019s the declarative option, and anything it can\u2019t do goes to Apex.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">See <\/span><span style=\"font-weight: 400;\">Flow vs Apex<\/span><span style=\"font-weight: 400;\"> for where that line sits.<\/span><\/p>\n<h2><b>The Four Flow Types<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">Pick by asking one question: What launches it?<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-19939\" src=\"https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-05_21_31-PM.webp\" alt=\"Which Salesforce flow type do you need?\" width=\"1536\" height=\"1024\" srcset=\"https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-05_21_31-PM.webp 1536w, https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-05_21_31-PM-1024x683.webp 1024w, https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-05_21_31-PM-768x512.webp 768w, https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-05_21_31-PM-640x427.webp 640w, https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-05_21_31-PM-400x267.webp 400w\" sizes=\"auto, (max-width: 1536px) 100vw, 1536px\" \/><\/p>\n<p><i><span style=\"font-weight: 400;\">Comparison of the four Salesforce flow types: Screen, Record-Triggered, Schedule-Triggered and Autolaunched, showing what launches each, typical uses and run context<\/span><\/i><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Screen Flow<\/b><span style=\"font-weight: 400;\">: A guided, multi-step interface. Data entry wizards, case creation, surveys, guided selling. The only type that takes user input mid-run.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Record-Triggered Flow<\/b><span style=\"font-weight: 400;\">: Fires when a record is created, updated, or deleted. The workhorse, and what replaced most Workflow Rules.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Schedule-Triggered Flow<\/b><span style=\"font-weight: 400;\">: Runs at a set time against a batch of records. Nightly cleanup, renewal reminders, data hygiene.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Autolaunched Flow<\/b><span style=\"font-weight: 400;\">: No trigger of its own; called by Apex, another flow, a button, or the API. This is what you build subflows as.<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">Beyond the core four, you\u2019ll also see <\/span><b>Flow Orchestration<\/b><span style=\"font-weight: 400;\"> for multi-user, multi-step processes with pauses and assignments (see <\/span><span style=\"font-weight: 400;\">Flow Orchestration<\/span><span style=\"font-weight: 400;\">), <\/span><b>approval processes<\/b><span style=\"font-weight: 400;\">, which are now built on Orchestration, and <\/span><b>template-triggered prompt flows<\/b><span style=\"font-weight: 400;\">, which inject generative AI into a process via Prompt Builder &#8211; the bridge between Flow and <\/span><span style=\"font-weight: 400;\">Agentforce<\/span><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p>&nbsp;<\/p>\n<h2><b>Before-Save or After-Save: The Decision That Drives Performance<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">Every record-triggered flow asks you this, and getting it wrong is the most common reason a flow is slow.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-19938\" src=\"https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-05_26_05-PM.webp\" alt=\"Before-save or after save? The Decision that drives performance\" width=\"1672\" height=\"941\" srcset=\"https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-05_26_05-PM.webp 1672w, https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-05_26_05-PM-1024x576.webp 1024w, https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-05_26_05-PM-768x432.webp 768w, https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-05_26_05-PM-1536x864.webp 1536w, https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-05_26_05-PM-640x360.webp 640w, https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-05_26_05-PM-400x225.webp 400w\" sizes=\"auto, (max-width: 1672px) 100vw, 1672px\" \/><\/p>\n<p><i><span style=\"font-weight: 400;\">Comparison of before-save and after-save record-triggered flows showing before-save updates same-record fields with no DML and runs ten times faster, while after-save handles related records<\/span><\/i><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>The Rule:<\/b><span style=\"font-weight: 400;\"> If you\u2019re only setting fields on the record that triggered the flow, use <\/span><b>before-save<\/b><span style=\"font-weight: 400;\">. It writes the values before the record is committed, so there\u2019s no second DML operation &#8211; measurably around 10\u00d7 faster than the after-save equivalent.<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">Everything else &#8211; creating related records, sending emails, calling actions, updating a parent &#8211; needs <\/span><b>after-save<\/b><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">One catch worth knowing: <\/span><i><span style=\"font-weight: 400;\">On a create, the record ID doesn\u2019t exist yet in a before-save flow, so anything needing the ID has to run after-save.<\/span><\/i><\/p>\n<h2><b>Building a Record-Triggered Flow<\/b><\/h2>\n<ol>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Setup \u2192 Flows \u2192 New Flow \u2192 Record-Triggered Flow.<\/b><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Choose the object and when it runs: Created, updated, created or updated, or deleted.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Set Entry Conditions:<\/b><span style=\"font-weight: 400;\"> Do this properly &#8211; a flow that runs on every save and then decides it has nothing to do is still consuming resources on every save.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Choose <\/span><b>before-save or after-save<\/b><span style=\"font-weight: 400;\"> using the rule above.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Add your logic<\/b><span style=\"font-weight: 400;\">: Decision elements to branch, Get Records to query, Assignment to set variables, Update\/Create Records to write<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Add <\/span><b>fault paths<\/b><span style=\"font-weight: 400;\"> to every element that touches data<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Debug it<\/b><span style=\"font-weight: 400;\"> with the built-in debugger, then test with realistic volume<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Activate<\/b><\/li>\n<\/ol>\n<p><span style=\"font-weight: 400;\">When flows become more complex or need to support broader business processes, <\/span><a href=\"https:\/\/dianapps.com\/salesforce-development-services\"><span style=\"font-weight: 400;\">Salesforce development services<\/span><\/a><span style=\"font-weight: 400;\"> can help with flow architecture, custom automation, Apex integrations, testing, and ongoing optimization.<\/span><\/p>\n<p><b>Optimise the Entry Conditions, Not the Logic:<\/b><span style=\"font-weight: 400;\"> The <\/span><span style=\"font-weight: 400;\">Is Changed<\/span><span style=\"font-weight: 400;\"> operator and the \u201conly when a record is updated to meet the condition requirements\u201d option are the two most underused settings in Flow Builder; they stop a flow re-running every time anything on the record changes.<\/span><\/p>\n<h2><b>Error Handling and Fault Paths<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">This is where most flows are weakest, and it\u2019s the difference between a flow that fails loudly and one that fails silently.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">A fault path is a branch that runs when an element fails, and without one, the user gets an unhelpful error screen, and the admin gets an email nobody reads.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Put a fault path on every Get, Create, Update, and Delete element.<\/span><\/p>\n<p><b>What to do inside it:<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Write the error to a custom logging object so you have a history.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Display a meaningful message on a screen flow, using <\/span><span style=\"font-weight: 400;\">{!$Flow.FaultMessage}<\/span><span style=\"font-weight: 400;\"> to surface the actual error text.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Notify an admin or a queue rather than an individual.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Never leave the fault path empty; an empty fault path silently swallows the failure, which is worse than no handling at all.<\/span><\/li>\n<\/ul>\n<p><b>The failures you\u2019ll actually see:<\/b><\/p>\n\n<table id=\"tablepress-255\" class=\"tablepress tablepress-id-255\">\n<thead>\n<tr class=\"row-1\">\n\t<th class=\"column-1\">Error<\/th><th class=\"column-2\">Cause<\/th>\n<\/tr>\n<\/thead>\n<tbody class=\"row-striping row-hover\">\n<tr class=\"row-2\">\n\t<td class=\"column-1\">UNABLE_TO_LOCK_ROW<\/td><td class=\"column-2\">Two automations updating the same record simultaneously - common on bulk loads<\/td>\n<\/tr>\n<tr class=\"row-3\">\n\t<td class=\"column-1\">FIELD_CUSTOM_VALIDATION_EXCEPTION<\/td><td class=\"column-2\">A validation rule blocked your update<\/td>\n<\/tr>\n<tr class=\"row-4\">\n\t<td class=\"column-1\">INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY<\/td><td class=\"column-2\">The running user lacks permission on a related record<\/td>\n<\/tr>\n<tr class=\"row-5\">\n\t<td class=\"column-1\">FIELD_INTEGRITY_EXCEPTION<\/td><td class=\"column-2\">A required lookup is empty or wrong<\/td>\n<\/tr>\n<tr class=\"row-6\">\n\t<td class=\"column-1\">Null reference errors<\/td><td class=\"column-2\">A Get Records element found nothing, and the flow used the result anyway<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<!-- #tablepress-255 from cache -->\n<p><span style=\"font-weight: 400;\">Always null-check after a Get because a Get Records that finds nothing doesn\u2019t fail &#8211; it returns null and the flow carries on until something downstream breaks confusingly.<\/span><\/p>\n<div style=\"background: #EEF2FE; border: 1px solid #DBE2FB; border-radius: 14px; padding: 28px 32px; margin: 38px 0;\">\n<h4 style=\"color: #1b3fae; font-size: 22px; line-height: 1.3; font-weight: bold; margin: 0 0 10px;\"><span style=\"font-weight: 400;\"><b>Flows failing in production and nobody knows why? <\/b><\/span><\/h4>\n<p style=\"color: #4b5563; font-size: 16px; line-height: 1.6; margin: 0 0 22px;\"><span style=\"font-weight: 400;\">Usually it\u2019s missing fault paths and no logging. We\u2019ll audit your automation and put proper error handling behind it.<\/span><\/p>\n<p><a style=\"display: inline-block; background: #2563EB; color: #ffffff; text-decoration: none; font-size: 15px; font-weight: 600; padding: 13px 26px; border-radius: 8px;\" href=\"https:\/\/dianapps.com\/salesforce-development-services\">Talk to our Salesforce development team \u2192<\/a><\/p>\n<\/div>\n<h2><b>Run Context: The Security Gotcha<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">This one catches experienced admins, and it\u2019s covered badly almost everywhere.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Screen Flows run in user mode by default as they respect the running user\u2019s object and field permissions.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Record-triggered and schedule-triggered flows always run in system mode. They ignore the running user\u2019s permissions entirely and can read and write anything.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">That\u2019s convenient, and it\u2019s a security exposure. A record-triggered flow can update fields the user could never edit directly, or surface data they have no access to, if you feed the result back to them. When you\u2019re building anything that touches sensitive data, treat run context as a design decision rather than a default.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">For screen flows, you can change the behaviour &#8211; run in system mode with or without sharing &#8211; but do it deliberately and document why.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Related: <\/span><span style=\"font-weight: 400;\">Salesforce compliance and data security<\/span><\/p>\n<h2><b>Flow Limits That Actually Bite<\/b><\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-19937\" src=\"https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-05_38_48-PM.webp\" alt=\"Flow Limits that actually bite\" width=\"1672\" height=\"941\" srcset=\"https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-05_38_48-PM.webp 1672w, https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-05_38_48-PM-1024x576.webp 1024w, https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-05_38_48-PM-768x432.webp 768w, https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-05_38_48-PM-1536x864.webp 1536w, https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-05_38_48-PM-640x360.webp 640w, https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/08\/ChatGPT-Image-Aug-11-2026-05_38_48-PM-400x225.webp 400w\" sizes=\"auto, (max-width: 1672px) 100vw, 1672px\" \/><\/p>\n<p><i><span style=\"font-weight: 400;\">Table of Salesforce Flow limits including 100 SOQL queries, 50000 records, 150 DML statements, 10 second CPU time, 50 versions per flow, and the removed 2000-element limit<\/span><\/i><\/p>\n<p><b>Two things most of you get wrong here.<\/b><\/p>\n<p><span style=\"font-weight: 400;\">First, the 2,000-element limit was removed in API version 57.0, but there are plenty of guides that still cite it. If your flow is on an older API version, you may still hit it &#8211; check the version before assuming.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Second, flows share the transaction budget with everything else. Your flow\u2019s queries, the Apex trigger firing on the same object, and any other flow on that record all draw from the same 100 SOQL and 150 DML allowance. A flow that\u2019s fine in isolation fails when it runs alongside a trigger.<\/span><\/p>\n<p><b>Staying inside the limits:<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Never Put Get, Create, Update, or Delete Inside A Loop:<\/b><span style=\"font-weight: 400;\"> This is the flow equivalent of SOQL in a loop and causes the same failures. Collect into a variable, act once outside the loop.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Use Before-Save<\/b><span style=\"font-weight: 400;\">: Where you can &#8211; it consumes no DML at all<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Filter In The Get Element<\/b><span style=\"font-weight: 400;\">: Not with a Decision afterwards<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Split Large Flows Into Subflows:<\/b><span style=\"font-weight: 400;\"> Rather than building one enormous canvas<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Move heavy work to schedule-triggered or asynchronous paths<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">Full reference: <\/span><span style=\"font-weight: 400;\">Salesforce governor limits<\/span><span style=\"font-weight: 400;\"> \u00b7 <\/span><a href=\"https:\/\/dianapps.com\/blog\/soql-and-sosl-in-salesforce\/\"><span style=\"font-weight: 400;\">SOQL guide<\/span><\/a><\/p>\n<h2><b>Subflows and Keeping Flows Maintainable<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">A subflow is an autolaunched flow called from another flow. Two reasons to use them:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Reuse:<\/b><span style=\"font-weight: 400;\"> Logic that appears in three flows should exist once.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Readability:<\/b><span style=\"font-weight: 400;\"> A flow with sixty elements on one canvas is unmaintainable regardless of whether it works. Break it into named subflows and the main flow becomes a readable summary of the process.<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">The practical threshold: <\/span><i><span style=\"font-weight: 400;\">If you can\u2019t understand the flow from one screen without scrolling, split it.<\/span><\/i><\/p>\n<h2><b>The \u201cOne Flow Per Object\u201d Debate<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">The old orthodoxy was one record-triggered flow per object per context, to keep execution order predictable. That guidance has genuinely shifted, and it\u2019s worth knowing why.<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>The Argument For One Flow:<\/b><span style=\"font-weight: 400;\"> You control the order of operations explicitly. Everything on that object is in one place.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>The Argument For Several:<\/b><span style=\"font-weight: 400;\"> A single flow handling every requirement for an object becomes an unmaintainable monolith, and different teams end up editing the same flow.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>What Changed:<\/b><span style=\"font-weight: 400;\"> The <\/span><b>Flow Trigger Explorer<\/b><span style=\"font-weight: 400;\"> lets you see every record-triggered flow on an object in the order it runs &#8211; and reorder them. That removes the main objection to having several, because order is now visible and controllable rather than implicit.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Where This Lands In Practice:<\/b><span style=\"font-weight: 400;\"> Several focused flows per object, each with a clear single purpose and a name that says what it does, with execution order set deliberately in Flow Trigger Explorer. Not one monolith, and not fifteen overlapping flows nobody has audited.<\/span><\/li>\n<\/ul>\n<h2><b>Testing and Auditing Flows<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">The Flow debugger runs a flow against real or specified data and shows the path taken and every variable at each step. Use it before activating anything.<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Test with volume:<\/b><span style=\"font-weight: 400;\"> A flow that works on one record can fail on two hundred. Debug with a bulk scenario, not a single happy path.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Flow Tests:<\/b><span style=\"font-weight: 400;\"> Let you save test configurations against a record-triggered flow and re-run them &#8211; closer to Apex unit testing than the debugger, and worth setting up for anything business-critical.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Lightning Flow Scanner<\/b><span style=\"font-weight: 400;\">: Is a free static analysis tool that scans flows for hardcoded IDs, unsafe run contexts, DML inside loops, missing fault paths, and recursion risks. Available as a VS Code extension and an unmanaged package. Almost nobody uses it, and it will find problems in your org today.<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">Related: <\/span><span style=\"font-weight: 400;\">Salesforce DevOps and CI\/CD<\/span><span style=\"font-weight: 400;\"> \u00b7 <\/span><span style=\"font-weight: 400;\">sandboxes and environment strategy<\/span><\/p>\n<h2><b>Migrating from Process Builder and Workflow Rules<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">If you still have them running, they\u2019re working on borrowed time as both are now retired.<\/span><\/p>\n<p><b>The approach:<\/b><\/p>\n<ol>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Inventory What You Have:<\/b><span style=\"font-weight: 400;\"> Setup \u2192 Process Builder and Workflow Rules, plus what each one actually does.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Don\u2019t Port One-To-One:<\/b><span style=\"font-weight: 400;\"> Several Process Builder nodes often collapse into one well-designed flow. Rebuilding beats translating.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Use The Migrate To Flow Tool:<\/b><span style=\"font-weight: 400;\"> For straightforward cases &#8211; it handles simple criteria and actions, and struggles with anything complex.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Rebuild The Complex Ones By Hand<\/b><span style=\"font-weight: 400;\">: Taking the opportunity to add fault paths the original never had.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Run Both In Parallel Briefly<\/b><span style=\"font-weight: 400;\">: Then deactivate the old one &#8211; never delete before you\u2019ve verified.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Watch For Duplicate Execution:<\/b><span style=\"font-weight: 400;\"> While both are active.<\/span><\/li>\n<\/ol>\n<p><b>One warning: deleted flows cannot be recovered.<\/b><span style=\"font-weight: 400;\"> There\u2019s no recycle bin. Deactivate first, delete much later.<\/span><\/p>\n<h2><b>Flow Best Practices<\/b><\/h2>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">One clear purpose per flow and a name that says what it is<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Entry conditions before logic &#8211; don\u2019t let a flow run then decide it shouldn\u2019t have<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Before-save for same-record updates<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Fault paths on every data element<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Null-check after every Get<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">No DML or Get inside loops<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">No hardcoded IDs &#8211; use custom labels, custom metadata or a Get<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Subflows for anything reused or anything long<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Description fields filled in, on the flow and on individual elements<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Deactivate rather than delete<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Review quarterly and remove what nobody uses<\/span><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<style>.elementor-19930 .elementor-element.elementor-element-2932a52{text-align:left;}.elementor-19930 .elementor-element.elementor-element-2932a52 > .elementor-widget-container{margin:0px 0px 0px 0px;}.elementor-19930 .elementor-element.elementor-element-0b767d1 .elementor-tab-title{border-width:1px;border-color:#00000014;}.elementor-19930 .elementor-element.elementor-element-0b767d1 .elementor-tab-content{border-width:1px;border-bottom-color:#00000014;}.elementor-19930 .elementor-element.elementor-element-0b767d1 > .elementor-widget-container{margin:0px 0px 0px 0px;}<\/style><div class=\"porto-block elementor elementor-19930\">\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-27707ca elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"27707ca\" data-element_type=\"section\">\r\n\t\t\t\r\n\t\t\t\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\r\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-0163611\" data-id=\"0163611\" data-element_type=\"column\">\r\n\r\n\t\t\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\r\n\t\t\t\t\t\t\t\t<div class=\"elementor-element elementor-element-03a2969 elementor-widget elementor-widget-text-editor\" data-id=\"03a2969\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t<style>\/*! elementor - v3.14.0 - 26-06-2023 *\/\n.elementor-widget-text-editor.elementor-drop-cap-view-stacked .elementor-drop-cap{background-color:#69727d;color:#fff}.elementor-widget-text-editor.elementor-drop-cap-view-framed .elementor-drop-cap{color:#69727d;border:3px solid;background-color:transparent}.elementor-widget-text-editor:not(.elementor-drop-cap-view-default) .elementor-drop-cap{margin-top:8px}.elementor-widget-text-editor:not(.elementor-drop-cap-view-default) .elementor-drop-cap-letter{width:1em;height:1em}.elementor-widget-text-editor .elementor-drop-cap{float:left;text-align:center;line-height:1;font-size:50px}.elementor-widget-text-editor .elementor-drop-cap-letter{display:inline-block}<\/style>\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-2932a52 elementor-widget elementor-widget-heading\" data-id=\"2932a52\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t<style>\/*! elementor - v3.14.0 - 26-06-2023 *\/\n.elementor-heading-title{padding:0;margin:0;line-height:1}.elementor-widget-heading .elementor-heading-title[class*=elementor-size-]>a{color:inherit;font-size:inherit;line-height:inherit}.elementor-widget-heading .elementor-heading-title.elementor-size-small{font-size:15px}.elementor-widget-heading .elementor-heading-title.elementor-size-medium{font-size:19px}.elementor-widget-heading .elementor-heading-title.elementor-size-large{font-size:29px}.elementor-widget-heading .elementor-heading-title.elementor-size-xl{font-size:39px}.elementor-widget-heading .elementor-heading-title.elementor-size-xxl{font-size:59px}<\/style><h2 class=\"elementor-heading-title elementor-size-large\">FAQs <\/h2>\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-0b767d1 elementor-widget elementor-widget-toggle\" data-id=\"0b767d1\" data-element_type=\"widget\" data-widget_type=\"toggle.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t<style>\/*! elementor - v3.14.0 - 26-06-2023 *\/\n.elementor-toggle{text-align:left}.elementor-toggle .elementor-tab-title{font-weight:700;line-height:1;margin:0;padding:15px;border-bottom:1px solid #d5d8dc;cursor:pointer;outline:none}.elementor-toggle .elementor-tab-title .elementor-toggle-icon{display:inline-block;width:1em}.elementor-toggle .elementor-tab-title .elementor-toggle-icon svg{-webkit-margin-start:-5px;margin-inline-start:-5px;width:1em;height:1em}.elementor-toggle .elementor-tab-title .elementor-toggle-icon.elementor-toggle-icon-right{float:right;text-align:right}.elementor-toggle .elementor-tab-title .elementor-toggle-icon.elementor-toggle-icon-left{float:left;text-align:left}.elementor-toggle .elementor-tab-title .elementor-toggle-icon .elementor-toggle-icon-closed{display:block}.elementor-toggle .elementor-tab-title .elementor-toggle-icon .elementor-toggle-icon-opened{display:none}.elementor-toggle .elementor-tab-title.elementor-active{border-bottom:none}.elementor-toggle .elementor-tab-title.elementor-active .elementor-toggle-icon-closed{display:none}.elementor-toggle .elementor-tab-title.elementor-active .elementor-toggle-icon-opened{display:block}.elementor-toggle .elementor-tab-content{padding:15px;border-bottom:1px solid #d5d8dc;display:none}@media (max-width:767px){.elementor-toggle .elementor-tab-title{padding:12px}.elementor-toggle .elementor-tab-content{padding:12px 10px}}.e-con-inner>.elementor-widget-toggle,.e-con>.elementor-widget-toggle{width:var(--container-widget-width);--flex-grow:var(--container-widget-flex-grow)}<\/style>\t\t<div class=\"elementor-toggle\">\n\t\t\t\t\t\t\t<div class=\"elementor-toggle-item\">\n\t\t\t\t\t<h3 id=\"elementor-tab-title-1201\" class=\"elementor-tab-title\" data-tab=\"1\" role=\"button\" aria-controls=\"elementor-tab-content-1201\" aria-expanded=\"false\">\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-toggle-icon elementor-toggle-icon-left\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-toggle-icon-closed\"><i class=\"fas fa-caret-right\"><\/i><\/span>\n\t\t\t\t\t\t\t\t<span class=\"elementor-toggle-icon-opened\"><i class=\"elementor-toggle-icon-opened fas fa-caret-up\"><\/i><\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t<a class=\"elementor-toggle-title\" tabindex=\"0\">What is Salesforce Flow used for?<\/a>\n\t\t\t\t\t<\/h3>\n\n\t\t\t\t\t<div id=\"elementor-tab-content-1201\" class=\"elementor-tab-content elementor-clearfix\" data-tab=\"1\" role=\"region\" aria-labelledby=\"elementor-tab-title-1201\"><p><span style=\"font-weight: 400;\">Automating business processes declaratively &#8211; updating records, routing work, sending notifications, guiding users through multi-step screens, and running scheduled batch jobs. It replaced Workflow Rules and Process Builder and handles the large majority of automation most orgs need without code.<\/span><\/p><\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t\t\t<div class=\"elementor-toggle-item\">\n\t\t\t\t\t<h3 id=\"elementor-tab-title-1202\" class=\"elementor-tab-title\" data-tab=\"2\" role=\"button\" aria-controls=\"elementor-tab-content-1202\" aria-expanded=\"false\">\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-toggle-icon elementor-toggle-icon-left\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-toggle-icon-closed\"><i class=\"fas fa-caret-right\"><\/i><\/span>\n\t\t\t\t\t\t\t\t<span class=\"elementor-toggle-icon-opened\"><i class=\"elementor-toggle-icon-opened fas fa-caret-up\"><\/i><\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t<a class=\"elementor-toggle-title\" tabindex=\"0\">What\u2019s the difference between before-save and after-save flows?<\/a>\n\t\t\t\t\t<\/h3>\n\n\t\t\t\t\t<div id=\"elementor-tab-content-1202\" class=\"elementor-tab-content elementor-clearfix\" data-tab=\"2\" role=\"region\" aria-labelledby=\"elementor-tab-title-1202\"><p><span style=\"font-weight: 400;\">Before-save flows update fields on the same record before it\u2019s committed, consuming no extra DML and running roughly 10\u00d7 faster. After-save flows run once the record is saved and can create, update, or delete related records, send emails, and call actions. Use before-save for same-record field updates only.<\/span><\/p><\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t\t\t<div class=\"elementor-toggle-item\">\n\t\t\t\t\t<h3 id=\"elementor-tab-title-1203\" class=\"elementor-tab-title\" data-tab=\"3\" role=\"button\" aria-controls=\"elementor-tab-content-1203\" aria-expanded=\"false\">\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-toggle-icon elementor-toggle-icon-left\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-toggle-icon-closed\"><i class=\"fas fa-caret-right\"><\/i><\/span>\n\t\t\t\t\t\t\t\t<span class=\"elementor-toggle-icon-opened\"><i class=\"elementor-toggle-icon-opened fas fa-caret-up\"><\/i><\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t<a class=\"elementor-toggle-title\" tabindex=\"0\">How do you handle errors in Salesforce Flow?<\/a>\n\t\t\t\t\t<\/h3>\n\n\t\t\t\t\t<div id=\"elementor-tab-content-1203\" class=\"elementor-tab-content elementor-clearfix\" data-tab=\"3\" role=\"region\" aria-labelledby=\"elementor-tab-title-1203\"><p><span style=\"font-weight: 400;\">With fault paths &#8211; an optional branch on Get, Create, Update and Delete elements that runs when that element fails. Inside it, log the error to a custom object, notify an admin, and surface the real message with <\/span><span style=\"font-weight: 400;\">{!$Flow.FaultMessage}<\/span><span style=\"font-weight: 400;\">. Never leave a fault path empty.<\/span><\/p><\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t\t\t<div class=\"elementor-toggle-item\">\n\t\t\t\t\t<h3 id=\"elementor-tab-title-1204\" class=\"elementor-tab-title\" data-tab=\"4\" role=\"button\" aria-controls=\"elementor-tab-content-1204\" aria-expanded=\"false\">\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-toggle-icon elementor-toggle-icon-left\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-toggle-icon-closed\"><i class=\"fas fa-caret-right\"><\/i><\/span>\n\t\t\t\t\t\t\t\t<span class=\"elementor-toggle-icon-opened\"><i class=\"elementor-toggle-icon-opened fas fa-caret-up\"><\/i><\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t<a class=\"elementor-toggle-title\" tabindex=\"0\">Can you have multiple record-triggered flows on the same object?<\/a>\n\t\t\t\t\t<\/h3>\n\n\t\t\t\t\t<div id=\"elementor-tab-content-1204\" class=\"elementor-tab-content elementor-clearfix\" data-tab=\"4\" role=\"region\" aria-labelledby=\"elementor-tab-title-1204\"><p><span style=\"font-weight: 400;\">Yes, and current guidance leans toward several focused flows rather than one monolith. Use <\/span><b>Flow Trigger Explorer<\/b><span style=\"font-weight: 400;\"> to see and reorder every flow on an object, so execution order is deliberate rather than implicit.<\/span><\/p><\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t\t\t<div class=\"elementor-toggle-item\">\n\t\t\t\t\t<h3 id=\"elementor-tab-title-1205\" class=\"elementor-tab-title\" data-tab=\"5\" role=\"button\" aria-controls=\"elementor-tab-content-1205\" aria-expanded=\"false\">\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-toggle-icon elementor-toggle-icon-left\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-toggle-icon-closed\"><i class=\"fas fa-caret-right\"><\/i><\/span>\n\t\t\t\t\t\t\t\t<span class=\"elementor-toggle-icon-opened\"><i class=\"elementor-toggle-icon-opened fas fa-caret-up\"><\/i><\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t<a class=\"elementor-toggle-title\" tabindex=\"0\">What are the limits on Salesforce Flow?<\/a>\n\t\t\t\t\t<\/h3>\n\n\t\t\t\t\t<div id=\"elementor-tab-content-1205\" class=\"elementor-tab-content elementor-clearfix\" data-tab=\"5\" role=\"region\" aria-labelledby=\"elementor-tab-title-1205\"><p><span style=\"font-weight: 400;\">Flows share the per-transaction budget: 100 SOQL queries, 50,000 records retrieved, 150 DML statements, 10 seconds CPU. Flow-specific limits include 50 versions per flow. The 2,000-element limit was removed in API version 57.0, though many guides still cite it.<\/span><\/p><\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t\t\t<div class=\"elementor-toggle-item\">\n\t\t\t\t\t<h3 id=\"elementor-tab-title-1206\" class=\"elementor-tab-title\" data-tab=\"6\" role=\"button\" aria-controls=\"elementor-tab-content-1206\" aria-expanded=\"false\">\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-toggle-icon elementor-toggle-icon-left\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-toggle-icon-closed\"><i class=\"fas fa-caret-right\"><\/i><\/span>\n\t\t\t\t\t\t\t\t<span class=\"elementor-toggle-icon-opened\"><i class=\"elementor-toggle-icon-opened fas fa-caret-up\"><\/i><\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t<a class=\"elementor-toggle-title\" tabindex=\"0\">Does Salesforce Flow run in system mode or user mode?<\/a>\n\t\t\t\t\t<\/h3>\n\n\t\t\t\t\t<div id=\"elementor-tab-content-1206\" class=\"elementor-tab-content elementor-clearfix\" data-tab=\"6\" role=\"region\" aria-labelledby=\"elementor-tab-title-1206\"><p><span style=\"font-weight: 400;\">Screen Flows run in user mode by default and respect the running user\u2019s permissions. Record-triggered and schedule-triggered flows always run in system mode, ignoring those permissions entirely. Treat run context as a security decision, not a default.<\/span><\/p><\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t\t\t<div class=\"elementor-toggle-item\">\n\t\t\t\t\t<h3 id=\"elementor-tab-title-1207\" class=\"elementor-tab-title\" data-tab=\"7\" role=\"button\" aria-controls=\"elementor-tab-content-1207\" aria-expanded=\"false\">\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-toggle-icon elementor-toggle-icon-left\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-toggle-icon-closed\"><i class=\"fas fa-caret-right\"><\/i><\/span>\n\t\t\t\t\t\t\t\t<span class=\"elementor-toggle-icon-opened\"><i class=\"elementor-toggle-icon-opened fas fa-caret-up\"><\/i><\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t<a class=\"elementor-toggle-title\" tabindex=\"0\">Is Process Builder still supported?<\/a>\n\t\t\t\t\t<\/h3>\n\n\t\t\t\t\t<div id=\"elementor-tab-content-1207\" class=\"elementor-tab-content elementor-clearfix\" data-tab=\"7\" role=\"region\" aria-labelledby=\"elementor-tab-title-1207\"><p><span style=\"font-weight: 400;\">No, both Process Builder and Workflow Rules are retired. Use the Migrate to Flow tool for simple cases and rebuild complex ones by hand &#8211; porting one-to-one usually recreates the original\u2019s problems.<\/span><\/p><\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t\t\t<div class=\"elementor-toggle-item\">\n\t\t\t\t\t<h3 id=\"elementor-tab-title-1208\" class=\"elementor-tab-title\" data-tab=\"8\" role=\"button\" aria-controls=\"elementor-tab-content-1208\" aria-expanded=\"false\">\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-toggle-icon elementor-toggle-icon-left\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-toggle-icon-closed\"><i class=\"fas fa-caret-right\"><\/i><\/span>\n\t\t\t\t\t\t\t\t<span class=\"elementor-toggle-icon-opened\"><i class=\"elementor-toggle-icon-opened fas fa-caret-up\"><\/i><\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t<a class=\"elementor-toggle-title\" tabindex=\"0\">Can you recover a deleted flow in Salesforce?<\/a>\n\t\t\t\t\t<\/h3>\n\n\t\t\t\t\t<div id=\"elementor-tab-content-1208\" class=\"elementor-tab-content elementor-clearfix\" data-tab=\"8\" role=\"region\" aria-labelledby=\"elementor-tab-title-1208\"><p><span style=\"font-weight: 400;\">No, deleted flows are permanently removed with no recycle bin and no recovery. Deactivate flows you think you no longer need and delete them only much later, once you\u2019re certain.<\/span><\/p><\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t\t\t<div class=\"elementor-toggle-item\">\n\t\t\t\t\t<h3 id=\"elementor-tab-title-1209\" class=\"elementor-tab-title\" data-tab=\"9\" role=\"button\" aria-controls=\"elementor-tab-content-1209\" aria-expanded=\"false\">\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-toggle-icon elementor-toggle-icon-left\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-toggle-icon-closed\"><i class=\"fas fa-caret-right\"><\/i><\/span>\n\t\t\t\t\t\t\t\t<span class=\"elementor-toggle-icon-opened\"><i class=\"elementor-toggle-icon-opened fas fa-caret-up\"><\/i><\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t<a class=\"elementor-toggle-title\" tabindex=\"0\">Why does my flow throw UNABLE_TO_LOCK_ROW?<\/a>\n\t\t\t\t\t<\/h3>\n\n\t\t\t\t\t<div id=\"elementor-tab-content-1209\" class=\"elementor-tab-content elementor-clearfix\" data-tab=\"9\" role=\"region\" aria-labelledby=\"elementor-tab-title-1209\"><p><span style=\"font-weight: 400;\">Two processes are updating the same record at the same time &#8211; commonly a flow and an Apex trigger, or a bulk data load hitting the same parent record repeatedly. Add a fault path, and look at whether the work can move to an asynchronous path.<\/span><\/p><h2>\u00a0<\/h2><\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t\t\t<script type=\"application\/ld+json\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@type\":\"FAQPage\",\"mainEntity\":[{\"@type\":\"Question\",\"name\":\"What is Salesforce Flow used for?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"<p><span style=\\\"font-weight: 400;\\\">Automating business processes declaratively &#8211; updating records, routing work, sending notifications, guiding users through multi-step screens, and running scheduled batch jobs. It replaced Workflow Rules and Process Builder and handles the large majority of automation most orgs need without code.<\\\/span><\\\/p>\"}},{\"@type\":\"Question\",\"name\":\"What\\u2019s the difference between before-save and after-save flows?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"<p><span style=\\\"font-weight: 400;\\\">Before-save flows update fields on the same record before it\\u2019s committed, consuming no extra DML and running roughly 10\\u00d7 faster. After-save flows run once the record is saved and can create, update, or delete related records, send emails, and call actions. Use before-save for same-record field updates only.<\\\/span><\\\/p>\"}},{\"@type\":\"Question\",\"name\":\"How do you handle errors in Salesforce Flow?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"<p><span style=\\\"font-weight: 400;\\\">With fault paths &#8211; an optional branch on Get, Create, Update and Delete elements that runs when that element fails. Inside it, log the error to a custom object, notify an admin, and surface the real message with <\\\/span><span style=\\\"font-weight: 400;\\\">{!$Flow.FaultMessage}<\\\/span><span style=\\\"font-weight: 400;\\\">. Never leave a fault path empty.<\\\/span><\\\/p>\"}},{\"@type\":\"Question\",\"name\":\"Can you have multiple record-triggered flows on the same object?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"<p><span style=\\\"font-weight: 400;\\\">Yes, and current guidance leans toward several focused flows rather than one monolith. Use <\\\/span><b>Flow Trigger Explorer<\\\/b><span style=\\\"font-weight: 400;\\\"> to see and reorder every flow on an object, so execution order is deliberate rather than implicit.<\\\/span><\\\/p>\"}},{\"@type\":\"Question\",\"name\":\"What are the limits on Salesforce Flow?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"<p><span style=\\\"font-weight: 400;\\\">Flows share the per-transaction budget: 100 SOQL queries, 50,000 records retrieved, 150 DML statements, 10 seconds CPU. Flow-specific limits include 50 versions per flow. The 2,000-element limit was removed in API version 57.0, though many guides still cite it.<\\\/span><\\\/p>\"}},{\"@type\":\"Question\",\"name\":\"Does Salesforce Flow run in system mode or user mode?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"<p><span style=\\\"font-weight: 400;\\\">Screen Flows run in user mode by default and respect the running user\\u2019s permissions. Record-triggered and schedule-triggered flows always run in system mode, ignoring those permissions entirely. Treat run context as a security decision, not a default.<\\\/span><\\\/p>\"}},{\"@type\":\"Question\",\"name\":\"Is Process Builder still supported?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"<p><span style=\\\"font-weight: 400;\\\">No, both Process Builder and Workflow Rules are retired. Use the Migrate to Flow tool for simple cases and rebuild complex ones by hand &#8211; porting one-to-one usually recreates the original\\u2019s problems.<\\\/span><\\\/p>\"}},{\"@type\":\"Question\",\"name\":\"Can you recover a deleted flow in Salesforce?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"<p><span style=\\\"font-weight: 400;\\\">No, deleted flows are permanently removed with no recycle bin and no recovery. Deactivate flows you think you no longer need and delete them only much later, once you\\u2019re certain.<\\\/span><\\\/p>\"}},{\"@type\":\"Question\",\"name\":\"Why does my flow throw UNABLE_TO_LOCK_ROW?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"<p><span style=\\\"font-weight: 400;\\\">Two processes are updating the same record at the same time &#8211; commonly a flow and an Apex trigger, or a bulk data load hitting the same parent record repeatedly. Add a fault path, and look at whether the work can move to an asynchronous path.<\\\/span><\\\/p><h2>\\u00a0<\\\/h2>\"}}]}<\/script>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\r\n\t\t\t\t<\/div>\r\n\t\t\t\t\t\t<\/div>\r\n\t\t\t\t<\/section>\r\n\t\t<\/div>\n<p>&nbsp;<\/p>\n<h2><b>Where to Go Next<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">For the decision about when code beats clicks, see <\/span><span style=\"font-weight: 400;\">Flow vs Apex<\/span><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">For multi-user, multi-step processes with pauses and approvals, see <\/span><span style=\"font-weight: 400;\">Flow Orchestration<\/span><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">For the limits every automation shares, see <\/span><span style=\"font-weight: 400;\">governor limits<\/span><span style=\"font-weight: 400;\">, and for the queries inside your Get elements, the <\/span><a href=\"https:\/\/dianapps.com\/blog\/soql-and-sosl-in-salesforce\/\"><span style=\"font-weight: 400;\">SOQL guide<\/span><\/a><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">For what else you can build without code, see <\/span><span style=\"font-weight: 400;\">Salesforce low-code development<\/span><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">For the wider picture, the <\/span><a href=\"https:\/\/dianapps.com\/blog\/salesforce-development-guide\/\"><span style=\"font-weight: 400;\">complete Salesforce development guide<\/span><\/a><span style=\"font-weight: 400;\"> is the hub.<\/span><\/p>\n<h2><b>When Automation Becomes the Problem<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">There\u2019s a point where an org has enough overlapping flows that nobody can safely change anything. Records update twice. Nobody knows which automation set a field. Every release breaks something unrelated.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">That\u2019s not a Flow problem &#8211; it\u2019s an automation architecture problem, and it doesn\u2019t fix itself.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">We\u2019re a certified Salesforce Consulting Partner, and untangling automation sprawl is routine work for us: mapping what fires when, consolidating overlapping flows, adding the error handling that was never there, and putting governance in place so it doesn\u2019t happen again.<\/span><\/p>\n<p><a href=\"https:\/\/dianapps.com\/salesforce-development-services\"><b>Book a Salesforce development scoping call \u2192<\/b><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Salesforce Flow is now the primary way to automate business processes in Salesforce without writing Apex. From updating records and routing work to guiding users through multi-step processes, Flow can handle a wide range of automation needs across a Salesforce org. But knowing the different types of Salesforce Flow is only the starting point. The [&hellip;]<\/p>\n","protected":false},"author":15,"featured_media":19936,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_yoast_wpseo_meta-robots-noindex":"","_yoast_wpseo_meta-robots-nofollow":"","_yoast_wpseo_canonical":"","_yoast_wpseo_opengraph-title":"","_yoast_wpseo_opengraph-description":"","_yoast_wpseo_opengraph-image":"","_yoast_wpseo_twitter-title":"","_yoast_wpseo_twitter-description":"","_yoast_wpseo_twitter-image":"","_wp_applaud_exclude":false,"footnotes":""},"categories":[85],"tags":[2580,2302],"class_list":["post-19926","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-salesforce","tag-guide-to-salesforce-flow","tag-salesforce-flow"],"featured_image_src":{"landsacpe":["https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/08\/Untitled-design-71-1140x445.webp",1140,445,true],"list":["https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/08\/Untitled-design-71-463x348.webp",463,348,true],"medium":["https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/08\/Untitled-design-71-300x169.webp",300,169,true],"full":["https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/08\/Untitled-design-71.webp",1536,864,false]},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>The Ultimate Guide to Salesforce Flow: Types, Practices and Errors<\/title>\n<meta name=\"description\" content=\"Learn Salesforce Flow types, before-save vs after-save flows, error handling, fault paths, limits, security, testing, and best practices.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/dianapps.com\/blog\/the-ultimate-guide-to-salesforce-flow\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"The Ultimate Guide to Salesforce Flow: Types, Practices and Errors\" \/>\n<meta property=\"og:description\" content=\"Learn Salesforce Flow types, before-save vs after-save flows, error handling, fault paths, limits, security, testing, and best practices.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/dianapps.com\/blog\/the-ultimate-guide-to-salesforce-flow\/\" \/>\n<meta property=\"og:site_name\" content=\"Learn About Digital Transformation &amp; Development | DianApps Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-08-11T12:20:53+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-08-11T12:30:25+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/08\/Untitled-design-71.webp\" \/>\n\t<meta property=\"og:image:width\" content=\"1536\" \/>\n\t<meta property=\"og:image:height\" content=\"864\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/webp\" \/>\n<meta name=\"author\" content=\"Vaibhav Sharma\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Vaibhav Sharma\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutes\" \/>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"The Ultimate Guide to Salesforce Flow: Types, Practices and Errors","description":"Learn Salesforce Flow types, before-save vs after-save flows, error handling, fault paths, limits, security, testing, and best practices.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/dianapps.com\/blog\/the-ultimate-guide-to-salesforce-flow\/","og_locale":"en_US","og_type":"article","og_title":"The Ultimate Guide to Salesforce Flow: Types, Practices and Errors","og_description":"Learn Salesforce Flow types, before-save vs after-save flows, error handling, fault paths, limits, security, testing, and best practices.","og_url":"https:\/\/dianapps.com\/blog\/the-ultimate-guide-to-salesforce-flow\/","og_site_name":"Learn About Digital Transformation &amp; Development | DianApps Blog","article_published_time":"2026-08-11T12:20:53+00:00","article_modified_time":"2026-08-11T12:30:25+00:00","og_image":[{"width":1536,"height":864,"url":"https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/08\/Untitled-design-71.webp","type":"image\/webp"}],"author":"Vaibhav Sharma","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Vaibhav Sharma","Est. reading time":"11 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/dianapps.com\/blog\/the-ultimate-guide-to-salesforce-flow\/#article","isPartOf":{"@id":"https:\/\/dianapps.com\/blog\/the-ultimate-guide-to-salesforce-flow\/"},"author":{"name":"Vaibhav Sharma","@id":"https:\/\/dianapps.com\/blog\/#\/schema\/person\/e0ee1e2a6cfb8681a3cc69154f8d8bcf"},"headline":"The Ultimate Guide to Salesforce Flow: Types, Best Practices and Error Handling","datePublished":"2026-08-11T12:20:53+00:00","dateModified":"2026-08-11T12:30:25+00:00","mainEntityOfPage":{"@id":"https:\/\/dianapps.com\/blog\/the-ultimate-guide-to-salesforce-flow\/"},"wordCount":2224,"commentCount":0,"image":{"@id":"https:\/\/dianapps.com\/blog\/the-ultimate-guide-to-salesforce-flow\/#primaryimage"},"thumbnailUrl":"https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/08\/Untitled-design-71.webp","keywords":["Guide to Salesforce Flow","Salesforce Flow"],"articleSection":["Salesforce"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/dianapps.com\/blog\/the-ultimate-guide-to-salesforce-flow\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/dianapps.com\/blog\/the-ultimate-guide-to-salesforce-flow\/","url":"https:\/\/dianapps.com\/blog\/the-ultimate-guide-to-salesforce-flow\/","name":"The Ultimate Guide to Salesforce Flow: Types, Practices and Errors","isPartOf":{"@id":"https:\/\/dianapps.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/dianapps.com\/blog\/the-ultimate-guide-to-salesforce-flow\/#primaryimage"},"image":{"@id":"https:\/\/dianapps.com\/blog\/the-ultimate-guide-to-salesforce-flow\/#primaryimage"},"thumbnailUrl":"https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/08\/Untitled-design-71.webp","datePublished":"2026-08-11T12:20:53+00:00","dateModified":"2026-08-11T12:30:25+00:00","author":{"@id":"https:\/\/dianapps.com\/blog\/#\/schema\/person\/e0ee1e2a6cfb8681a3cc69154f8d8bcf"},"description":"Learn Salesforce Flow types, before-save vs after-save flows, error handling, fault paths, limits, security, testing, and best practices.","breadcrumb":{"@id":"https:\/\/dianapps.com\/blog\/the-ultimate-guide-to-salesforce-flow\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/dianapps.com\/blog\/the-ultimate-guide-to-salesforce-flow\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/dianapps.com\/blog\/the-ultimate-guide-to-salesforce-flow\/#primaryimage","url":"https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/08\/Untitled-design-71.webp","contentUrl":"https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/08\/Untitled-design-71.webp","width":1536,"height":864,"caption":"The ultimate guide to salesforce flow: Types, best practices and error handling"},{"@type":"BreadcrumbList","@id":"https:\/\/dianapps.com\/blog\/the-ultimate-guide-to-salesforce-flow\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/dianapps.com\/blog\/"},{"@type":"ListItem","position":2,"name":"The Ultimate Guide to Salesforce Flow: Types, Best Practices and Error Handling"}]},{"@type":"WebSite","@id":"https:\/\/dianapps.com\/blog\/#website","url":"https:\/\/dianapps.com\/blog\/","name":"Learn About Digital Transformation &amp; Development | DianApps Blog","description":"Dianapps","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/dianapps.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/dianapps.com\/blog\/#\/schema\/person\/e0ee1e2a6cfb8681a3cc69154f8d8bcf","name":"Vaibhav Sharma","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/07\/cropped-Vaibhav-Sharma-Salesforce-Specialist-96x96.jpg","url":"https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/07\/cropped-Vaibhav-Sharma-Salesforce-Specialist-96x96.jpg","contentUrl":"https:\/\/dianapps.com\/blog\/wp-content\/uploads\/2026\/07\/cropped-Vaibhav-Sharma-Salesforce-Specialist-96x96.jpg","caption":"Vaibhav Sharma"},"description":"A Salesforce specialist with over 15 years in the field, Vaibhav Sharma has built his career at the intersection of CRM strategy and enterprise transformation. As the driving force behind Salesforce innovation at DianApps, he architects solutions across Sales Cloud, Service Cloud, and Experience Cloud that turn fragmented customer data into unified growth engines. His work spans a 360-degree perspective in BFSI, healthcare, and retail, where he's known for engineering platforms that don't just go live, they move revenue and retention numbers. Vaibhav's edge lies in reading where Salesforce is headed next, from AI-powered automation, AgentExchange to Agentforce, and translating that foresight into roadmaps enterprise leaders can act on today.","url":"https:\/\/dianapps.com\/blog\/author\/vaibhav-sharma\/"}]}},"_links":{"self":[{"href":"https:\/\/dianapps.com\/blog\/wp-json\/wp\/v2\/posts\/19926","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dianapps.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dianapps.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dianapps.com\/blog\/wp-json\/wp\/v2\/users\/15"}],"replies":[{"embeddable":true,"href":"https:\/\/dianapps.com\/blog\/wp-json\/wp\/v2\/comments?post=19926"}],"version-history":[{"count":4,"href":"https:\/\/dianapps.com\/blog\/wp-json\/wp\/v2\/posts\/19926\/revisions"}],"predecessor-version":[{"id":19942,"href":"https:\/\/dianapps.com\/blog\/wp-json\/wp\/v2\/posts\/19926\/revisions\/19942"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/dianapps.com\/blog\/wp-json\/wp\/v2\/media\/19936"}],"wp:attachment":[{"href":"https:\/\/dianapps.com\/blog\/wp-json\/wp\/v2\/media?parent=19926"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dianapps.com\/blog\/wp-json\/wp\/v2\/categories?post=19926"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dianapps.com\/blog\/wp-json\/wp\/v2\/tags?post=19926"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}