CloudAvant
Comparison · Architecture & Technical Debt · For Developers & Architects

Flow vs. Apex: Most Teams Pick by Habit, Not by What Breaks First

Flow has absorbed most of what used to be Apex's exclusive territory, which is exactly why more orgs get the Flow vs. Apex call wrong - not because the two are obviously different, but because the real differences left are invisible until something breaks. Here's the decision test that holds up, and the case studies hiding in your own org's automation.

CloudAvant Team9 min read

What you’ll learn

  • Why 'can Flow do it?' stopped being a useful question once Flow could call invocable Apex, handle bulk work, and run async paths - and what question replaced it.
  • The governor-limit budget every Flow and Apex trigger on an object shares, and why the '101' error usually isn't caused by whatever you just added.
  • The one place Flow actually gives you more control than Apex does by default - execution order - and why most orgs never configure it.
  • What Winter '27's new Flow Test Mode (Beta) changes about the testing gap, and what it doesn't.

Flow can call invocable Apex, run on scheduled and asynchronous paths, handle bulk record updates without anyone writing a trigger, and - as of Winter '27 - get a real test mode with coverage reporting. Three years ago, 'default to Flow unless you have a clear reason to write Apex' was useful advice because Flow hit real walls constantly: no bulk-safe recursion handling, no callouts, no way to test anything short of clicking through it by hand. Most of those walls have moved or disappeared. Which means the easy version of the Flow vs. Apex decision - can Flow technically do this - stopped being the right question, because the answer is almost always yes now. The question that still decides it is what breaks first as the requirement grows, and that's a much narrower, more specific test than 'click or code.'

This shows up constantly in Salesforce Health & Roadmap reviews: an object carrying four or five record-triggered flows and two Apex triggers, each one individually defensible, each one picked by whoever was confident with that tool the week it got built, with no shared rule connecting any of the choices. None of those automations is wrong on its own. The problem is that nobody decided the order they run in, and nobody is watching the one resource all of them draw from at the same time - a theme that runs through how AI-generated Flows have accelerated the same kind of sprawl.

The short answer

In brief: default to Flow for anything a business user would recognise as 'the way we work here' - approvals, record updates, screen-guided processes, anything likely to change again within a year. Reach for Apex when a requirement needs transactional logic or recursion handling Flow can't express cleanly, bulk processing across tens of thousands of records in one job, a callout that has to complete synchronously inside the save transaction, or a change-management process that genuinely requires enforced unit-test coverage before deployment. Most real requirements that arrive as 'Flow or Apex' turn out to be 'Flow, calling a narrow piece of Apex for the one part that needs it' - a hybrid, not a binary choice. And if the object in question already has several flows and triggers stacked on it with no explicit order between them, the more urgent decision isn't which tool to add next. It's consolidating what's already there.

Why the old Flow vs. Apex rule of thumb stopped working

Flow's real gap against Apex used to be capability: it couldn't make synchronous callouts, couldn't cleanly handle bulk operations without hitting limits fast, and had no equivalent to a unit test. Invocable Apex actions closed the first gap years ago - a Flow can hand off the one piece of logic it genuinely can't express and keep everything else declarative. Scheduled and autolaunched paths closed most of the bulk-processing gap. What's left isn't a capability gap anymore. It's a set of specific, technical constraints that decide the call for you regardless of which tool is more comfortable for whoever's building it - and those constraints are the actual decision test.

The shared governor budget nobody checks

A Salesforce transaction allows up to 100 SOQL queries and 150 DML statements in a synchronous context, or 200 queries in an asynchronous one - and that ceiling applies to the whole transaction, not to whichever Flow or Apex trigger happens to be running. If an object already carries three record-triggered flows and two Apex triggers, every Get Records element and every query inside those triggers draws from the same shared pool. The 'Too many SOQL queries: 101' error that gets blamed on whatever was added last is usually the accumulated cost of everything already stacked on that object - the new automation just happened to be the one that tipped it over. This is the first real test: before adding a sixth automation to an object, know what the other five are already spending, not just what the new one needs.

Execution order: the one place Flow beats Apex

Salesforce's own order-of-execution runs before-save record-triggered flows ahead of before-triggers - so if a before-save flow sets a field, a before-trigger reading that field sees the new value, not the old one. That ordering matters for correctness, not just style, and it's easy to get backwards when flows and triggers on the same object were built months apart by different people. Where it gets interesting is what happens when there's more than one automation of the same kind. Multiple Apex triggers on one object have no guaranteed order - which is exactly why the standard fix is one trigger per object, delegating to handler classes, rather than trusting Salesforce to run them in a sensible sequence. Flow, by contrast, gives you an explicit Trigger Order value (1 to 2,000, lower runs first) in a flow version's advanced settings, so record-triggered flows on the same object run in a sequence you actually chose - though it doesn't apply to scheduled or asynchronous paths. Most orgs never set it, which means flows are falling back to an undocumented default order nobody chose either. The honest trade-off: Apex's ordering problem is older and better understood, with mature frameworks built to solve it. Flow's ordering control is newer, built in, and sitting unused in most orgs that would benefit from it.

Flow, Apex, hybrid, or neither

SituationChooseWhy
Business logic a non-developer should be able to read and adjustFlowMaintainability beats raw performance for anything that will change again within a year
Bulk processing across tens of thousands of records, or complex recursive calculationsApexCode gives tighter control over the same governor-limit budget Flow has to share
A callout that must complete synchronously before the record savesApex (invoked from Flow if the rest of the process is declarative)Flow can call this logic through an invocable action; it can't make the callout itself in that context
One business process, most of it simple, with one genuinely hard stepHybrid - Flow calling a narrow invocable Apex methodKeeps the readable majority declarative without forcing the hard 10% into a workaround
An object already has several flows and triggers with no shared order or limit budgetNeither - consolidate firstAdding a sixth automation to an unmanaged stack is how the next 101 error gets written
A change process that legally or contractually requires enforced test coverage before deploymentApex, for nowFlow Test Mode (Beta) narrows this gap but isn't an enforced deployment gate the way Apex code coverage is

100 / 200

SOQL queries per transaction - synchronous vs. asynchronous context - shared across every Flow and Apex trigger running in it

150

DML statements allowed per transaction, same shared budget

1-2,000

Trigger Order range available on a record-triggered flow's advanced settings - lower numbers run first

From the field

CloudAvant's villa construction-lifecycle platform work for Aldar is a genuine example of the hybrid answer, not the binary one. The vendor-facing Experience Cloud portal needed to feel simple and guided for external vendors and internal stakeholders, which argued for Flow - but the handoffs between parties, the record state changes, and the automated steps that cut manual coordination out of the construction lifecycle were built with Flow and Apex together, each one doing the part it was suited for. Nobody on that engagement needed to win a 'Flow vs. Apex' argument. They needed the handoff to stop requiring a phone call.

What Winter '27 actually changes, and what it doesn't

Flow Test Mode (Beta) is the most relevant Winter '27 change to this decision. It's opt-in - enabled under Process Automation Settings - and replaces the old debug-only experience with a proper Build/Test split in Flow Builder: saved, repeatable tests, coverage reporting, and canvas highlighting that shows which paths through a flow were never exercised. Salesforce has scoped the beta to record-triggered and autolaunched flows, with screen and scheduled flows planned for later. That's a real narrowing of Flow's testing gap against Apex, and worth adopting in a sandbox now rather than waiting for GA. It is not, however, an enforced deployment gate. Apex's 75% org-wide code-coverage requirement blocks a production deployment outright; nothing in Flow Test Mode today stops a flow with zero test coverage from shipping. For a change process that genuinely needs enforced pre-deployment testing - a regulated environment, a large team shipping daily - that specific difference still points to Apex, or to a release process that treats Flow Test Mode as a discipline the team imposes on itself rather than one the platform imposes for them.

A few questions worth asking before the next build

Can Flow replace Apex entirely now?

No. It can replace most of what used to require Apex for convenience rather than necessity - which is the majority of ordinary business automation. What it still can't do on its own is bulk-safe complex transactional logic, a synchronous callout inside its own execution context, or satisfy a deployment process that requires enforced unit-test coverage. Those requirements don't disappear just because Flow got more capable everywhere else.

Does a Salesforce Flow run before or after an Apex trigger?

A before-save record-triggered flow runs before the object's before-triggers, so any field value it sets is visible to before-trigger logic that reads it afterward. An after-save flow runs later, once triggers and other save-order processing have already happened - which is also why after-save is the required choice for anything that needs to touch a related record rather than just the record that triggered it. Getting this backwards is a common, quiet cause of logic that works in isolation but misbehaves once both a flow and a trigger exist on the same object.

What's the first thing to check on an object that already has both?

Pull the debug logs for that object's save path and see how much of the 100/150 governor budget is already committed before anyone adds anything new. Then confirm every record-triggered flow on it has an explicit Trigger Order value rather than an unset default, and confirm there's exactly one Apex trigger with logic delegated to handler classes rather than several triggers with no defined order between them. That audit usually takes less time than the next automation request, and it tells you whether the org can safely add one more thing or needs to consolidate first.

The bottom line

Flow vs. Apex stopped being a debate about which tool is more powerful a while ago - Flow can reach almost everywhere Apex can now, by calling it when it needs to. What it hasn't stopped being is a debate about which tool is more defensible when something goes wrong: who can read the logic at 2am, how much of the shared governor budget is already spent, whether the execution order was chosen or inherited, and whether the next change can be tested before it ships or only after. Answer those four questions for a specific requirement and the Flow-or-Apex call mostly makes itself. If nobody in your org can currently answer them for the objects carrying the most automation, that's worth finding out in a Salesforce Health & Roadmap review before the next flow or trigger gets added on top. Talk to an architect if it's already past the point of a quick audit.

Not sure how much automation your org has stacked on one object, or in what order it runs?

Written by CloudAvant Team - Senior Salesforce consultants and architects with hands-on enterprise delivery experience across Sales Cloud, Service Cloud, Experience Cloud, and complex multi-region implementations. More about CloudAvant.