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.
Real-World Application
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 Recordselement 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
- 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
DMLand 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 Recordsfor reference data. They cannot create records, update other records, execute actions, send emails, make callouts, or run subflows that performDML. - The Mirror: Using after-save to update the triggering record issues a real
DMLstatement. 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?
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
$Recordvariable 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.