Flow vs Apex: when to stay declarative in Salesforce
A practical decision tree for Salesforce development — when Flow is enough, when you need Apex, and when both together cause bugs.
Every Salesforce development engagement hits the same fork: can this be a Flow, or do we write Apex?
Declarative-first is the right default. Flows are versioned, visible to admins, and cheaper to hand off. But teams that refuse to write code often end up with screen Flows that should have been a Lightning page, or record-triggered Flows that fire in the wrong order.
Start with Flow when
- Single-object logic — field updates, email alerts, subflow calls on create/update.
- Admin-maintainable rules — discount approval thresholds that ops will tweak quarterly.
- Guided user actions — screen Flows for case intake or lead qualification with a few branches.
Use before-save record-triggered Flows for field stamping when you can. They are faster than after-save and avoid extra DML.
Reach for Apex when
- Bulk complexity — you need to aggregate across thousands of related records in one transaction.
- Callouts with nuanced retry — HTTP integrations with custom backoff, signing, or payload transforms Flow cannot express cleanly.
- Performance-sensitive paths — hot objects with tight latency SLAs where Flow overhead shows up in profiling.
- Reusable libraries — shared validation or calculation logic called from Flow, LWC, and batch jobs.
The messy middle (both)
Apex invocable actions called from Flow work well for testable business logic. The anti-pattern is duplicating the same rule in a trigger and a Flow on the same event — order of execution in Salesforce is unforgiving.
Our rule: one source of truth per object event. Document it in the repo README admins can find.
Need help untangling an org where every consultant added another Flow? That is a common Salesforce implementation rescue for us — get in touch.