Skip to main content

The Ultimate Guide to Salesforce Flows: Before-Save vs. After-Save (10x Faster Updates)

💬 In plain words: Before-save updates in Salesforce are entirely free from a performance standpoint. Because the record is already open in memory, you are simply writing on it before it gets saved. After-save updates, however, force the system to re-open the record and run the entire save process all over again, essentially doubling your resource cost. The golden rule is simple: if you are changing the exact same record that triggered the flow, do it before the save. If you are updating related records, do it after the save.
Salesforce Flow Before-save vs After-save Performance comparison chart

The Core Concept: Memory vs. Database

A before-save flow modifies a record while it is still in the system's memory, right before it is permanently written to the database.

  • No extra operations: It doesn't require an additional DML (Data Manipulation Language) statement, meaning no second save cycle.
  • Lightning fast: Because triggers don't re-fire, Salesforce states that before-save updates are roughly 10x faster than equivalent after-save updates.
  • After-save limitations: An after-save flow looks at the committed database values. It is perfectly designed to interact with other records, send out platform events, or call subflows. However, using it to update the record that just triggered it creates a massive performance drag.
🧠 Core Rule: Keep same-record field updates in before-save. Move side effects and related-record updates to after-save.

Real-World Application

🎬 Real-Life Example: The Field Update That Cost Double

Imagine a company called Skyline that stamps a "Priority" level on every new Delivery record based on the type of service selected.

The Old/Bad Way: An after-save flow uses an Update Records element on the exact Delivery record that just triggered the flow.
Why it fails at scale: The after-save process forces Salesforce to re-open the freshly saved record and run the entire save pipeline again. Triggers fire twice, and you pay double the processing limits. During bulk data loads, this is a massive bottleneck.

The New/Good Way:
  • Rebuild the automation as a before-save flow.
  • Assign the new priority value directly to $Record.Priority__c.
  • Remove the Update Records element entirely—the new value simply rides along with the original save.
  • Reserve after-save flows strictly for updating other related records, sending emails, and handling integrations.

The Payoff: By processing 10x faster, nightly bulk data loads drop from taking several minutes down to mere seconds.

The 360 Breakdown

🧭 360 Card — Before-Save vs. After-Save
  • The Rule: Same-record updates go before-save. Cross-record updates go after-save.
  • The Gain: Writing before a save is free. The record is already open in memory, eliminating extra DML and a second save cycle.
  • The Price (Limits): Before-save flows are highly restricted. They can only update fields on the triggering record and use Get Records for reference data. They cannot create records, update other records, execute actions, send emails, make callouts, or run subflows that perform DML.
  • The Mirror: Using after-save to update the triggering record issues a real DML statement. This forces Salesforce to re-enter the order of execution and fire every trigger a second time.
  • At Volume: A single unnecessary after-save flow running on a 10,000-row data load results in 10,000 completely wasted save cycles. Moving same-record updates down a stage is the cheapest performance fix in most inherited orgs.

Core Q&A

Q: Why exactly is a same-record update in an after-save flow so expensive?

🎯 The Trap: Because it starts a completely new save transaction! All your validation rules, before-save flows, Apex triggers, and workflow rules are forced to run a second time. It doubles your resource cost.

A: It issues a real DML update on a record that was just saved. That action forces the record back into the Salesforce order of execution.

  • System validations, before-save flows, before triggers, validation rules, after triggers, and workflows all run again.
  • This execution loop is exactly why developers have to build complex recursion guards.
  • Conversely, a simple before-save assignment to the $Record variable avoids all of this overhead. The new value is seamlessly folded into the very first database write.

Scenario-Based Follow-Ups

Q: What CAN'T a before-save flow do, and how do you handle a requirement that needs both phases?

A: A before-save flow is strictly limited to assigning field values on the $Record variable and running Get Records to fetch reference data.

  • It cannot process actions, send emails, execute callouts, or run subflows that contain DML.
  • If a business requirement asks you to "stamp a category on this record AND open a follow-up task," you must split the logic.
  • The category stamping belongs in a before-save flow. The task creation belongs in an after-save flow, utilizing an entry condition to trigger only when the category transition happens.
  • Presenting requirements as phase-split pairs is the fluent answer for a clean architecture.

Q: You inherit an org where every record-triggered flow is after-save because "that is how the first one was built." How do you quantify the impact of fixing this to stakeholders?

A: Start by measuring the current state. Run debug logs on a representative bulk save operation to capture the total CPU time and DML consumption before making any changes.

  • By relocating same-record updates to before-save, you eliminate one full save cycle per record for every offending flow.
  • For example, on a 200-record batch load with two inefficient after-save flows, you are avoiding 400 unnecessary pipeline executions.
  • This optimization frequently cuts the overall save time by half or more and drastically shrinks database lock windows during high-volume data loads.
  • The pitch: Frame this project to stakeholders as an initiative to increase system capacity, not just technical elegance. The headroom you recover will allow the org to absorb peak processing loads that previously triggered limit exceptions and locking errors.