Optimizing Record-triggered flows for performance
If you're building automation today, you're almost certainly using Record-triggered flows. But I've noticed a lot of people still struggle with the "When to Run the Flow" setting. It looks like a small choice, and picking the wrong option gives you sluggish page loads or weird data issues that are a pain to debug later.
In my experience, most teams default to After-Save because it feels safer. They want access to everything. That's usually a mistake. If you're only updating a field on the same record that triggered the flow, you're wasting resources by waiting until after the record hits the database.
Record-triggered flows: When to use Before-Save vs After-Save
The short answer? If you're updating the record itself, go Before-Save. If you're doing literally anything else, go After-Save. Nothing in Salesforce is ever quite that simple, though, so it helps to know why. Following best practices for Salesforce Flow means understanding the order of execution.
The "Fast Field Update" (Before-Save)
Before-Save flows are fast because they run before the record is saved to the database. Think of it like a quick check-and-fix before the mailman picks up the envelope. Since the record isn't "committed" yet, the flow can swap out values on the fly without needing a separate update command. That saves a ton of CPU time and avoids the whole "re-triggering" mess that happens with older workflow rules or Process Builder.
I've seen teams try to use these for everything, but they have limits. You can't update related records, you can't send emails, and you can't call external systems. It's strictly for "on-record" work like normalizing phone numbers or setting a default category based on an Amount field.
The "Actions and Related Records" (After-Save)
After-Save is where the heavy lifting happens. These Record-triggered flows run after the record is committed, which is the only way you'll get a Record ID for a brand-new record. If you need to create a Task, update a parent Account, or send a Slack notification, this is your only option.
One thing that trips people up is the performance cost. Because the record is already saved, any update the flow makes counts as a second save operation. If you aren't careful with bulk record processing in Flows, you'll hit governor limits faster than you'd think. It's also where you're more likely to run into recursion issues if your flow updates something that triggers another flow.
Pro tip: if you find yourself writing complex logic that needs to decide between Flow and code, check out this guide on Apex vs Flow. Sometimes a trigger is still the better move for high-volume objects.
How they stack up: a quick comparison
Here is how the two compare. I keep this checklist in my head when I'm starting a new project.
| Feature | Before-Save (Fast Update) | After-Save (Actions) |
|---|---|---|
| Speed | Lightning fast (no extra DML) | Slower (requires extra DML) |
| Record ID | Available (usually), but not final | Fully available and committed |
| Related Records | Read-only access only | Can create/update/delete |
| Emails & Actions | Not supported | Fully supported |
| External Callouts | No | Yes (via Async paths) |
Real-world scenarios
I recently worked on a project where the client wanted to automate their Lead intake. Here's how we split the work between the two types of Record-triggered flows.
Scenario 1: The Before-Save approach
When a Lead comes in, we needed to make sure the "Source" field was capitalized and set a "Rating" based on the industry. Since we only cared about the Lead record itself, we used a Before-Save flow.
// Trigger: Lead is created or updated
// Logic:
If (Lead.Industry == 'Technology') {
Lead.Rating = 'Hot';
}
Lead.LeadSource = UpperCase(Lead.LeadSource);
// Result: No extra DML. The save finishes with these values already set.
Scenario 2: The After-Save approach
Once that Lead is saved, the sales manager wanted a Task created for the owner and a notification sent to a specific Slack channel. This requires a Record ID and an external action, so it has to be After-Save.
// Trigger: Lead is created
// Action 1: Create Record (Task)
// Action 2: Send Custom Notification or Slack Action
// Result: The Lead exists in the DB, so the Task can be linked to it correctly.
Key takeaways for Record-triggered flows
- Start with Before-Save. Ask yourself "Can I do this with a Fast Field Update?" If the answer is yes, don't even look at After-Save.
- Mind the ID. If your logic relies on a Record ID for a new record (like for a junction object), you must use After-Save.
- Watch your limits. After-Save flows are more expensive in terms of CPU time. If you have a lot of them on one object, you'll feel it.
- Avoid recursion with entry conditions. Most teams get this wrong. Don't let your flow run unless the specific fields you care about have actually changed.
Don't click "Actions and Related Records" because it's the default. Take ten seconds to think about whether you're only updating the triggering record or reaching out to the rest of the org.
Leave a Comment