← All articles

GTM Systems

We Had 282 Automations and Nobody Could Say What Half of Them Did

Five years of "just add one more flow" left an org where a single lead save fired eleven automations and changing anything was russian roulette. Here is how to audit an accreted stack, find the dead weight, and consolidate it without breaking production.

· 8 min read

The number was 282. That was the count of active automations in an org I was asked to stabilize: workflow rules, process builder processes, record-triggered flows, and Apex triggers, spread across a dozen objects, built by a rotating cast over five years. A single lead save fired eleven of them. Nobody on the team could tell me what more than half of them did, whether they were still needed, or what would break if we turned one off. Every request to change lead handling had become a negotiation with a black box, and the standard answer had calcified into “do not touch it, just add a new flow that does what you need.” So the number only ever went up.

That is automation debt, and it is the systems analog of the code debt every engineering team knows. Each automation was a reasonable decision in its moment. The accumulated interest is an org where nobody understands the whole, changes are high-risk, and the safest-feeling move (add another automation) is the one that makes the debt worse. Paying it down is a real project with a real method: audit what exists, prove what is dead, consolidate what overlaps, and put a governor on new additions so the pile does not regrow.

282
Active automations across the org
11
Fired on a single lead save
~50%
Nobody could explain the purpose of

Debt compounds because the safe move makes it worse

The vicious part of automation debt is that the risk-averse choice grows the debt. When nobody understands the existing stack, editing an automation feels dangerous, so the team routes around it by adding a new one. Each addition raises the interaction count and lowers the odds anyone will ever understand the whole, which makes the next person even more likely to add rather than edit. The stack does not grow linearly; it compounds, because the debt itself discourages the paydown. Left alone, an org goes from “a few flows” to “do not touch anything” in about the time it takes for the original authors to leave.

Active automation count over five years of 'just add one'
Nobody set out to build 282 automations. Each year, requests turned into additions because editing the black box felt too risky, and the count compounded. The paydown at year five is not fewer features; it is the same behavior expressed in far fewer, understood artifacts.
View as table
PointValue
Y140
Y295
Y3160
Y4230
Y5282
After82

Audit first: you cannot pay down what you cannot see

The paydown starts with a full inventory, because the reason the debt persists is that no one can see the whole. Pull every automation with its object, trigger, active status, last-modified date, and the fields it reads and writes. The Tooling API and Metadata API give you flows, workflow rules, and triggers; a FieldDefinition and dependency query gives you what references what. The output is one table with a row per automation. That table alone changes the conversation, because “we have 282, forty of them have not been modified in three years, and eleven fire on a lead save” is a fact the team can act on, where “the org is messy” is not.

The paydown pipeline Inventory, classify, consolidate, govern
Inventoryone row per automationClassifydead / dup / keepConsolidateoverlaps into oneGovernstop the regrowth
You cannot consolidate a stack you have not inventoried. The audit produces the table; classification finds the dead and the duplicated; consolidation folds overlaps into one artifact; governance stops the pile from regrowing.

Classify into dead, duplicated, and load-bearing

With the table in hand, sort every automation into three buckets. Dead: it references a field, record type, or picklist value that no longer exists, or its entry criteria can never be true, so it never fires. Duplicated: two or more automations do overlapping work on the same object and save. Load-bearing: it does real, unique work you must preserve. The dead bucket you retire outright after confirming it truly never fires. The duplicated bucket is the consolidation target. The load-bearing bucket you leave alone except to fold it into the consolidated flow for its object. A query like this finds a class of dead automation fast.

-- Flows not modified in over two years are prime suspects for the dead
-- bucket. Cross-reference against debug logs to confirm they never fire
-- before retiring, but this narrows 282 to a reviewable shortlist.
SELECT DeveloperName, TriggerType, Status, LastModifiedDate
FROM FlowDefinitionView
WHERE Status = 'Active'
  AND LastModifiedDate < LAST_N_DAYS:730
ORDER BY LastModifiedDate ASC

The worked example: 282 down to 82 without breaking prod

An accreted stack versus a paid-down one

Accreted stack (282) Paid-down stack (82)
Automations on a lead save Eleven, order undefined Two, ordered on purpose
Understood by the team About half All of them
Changing lead handling "Do not touch it, add a flow" Edit the one flow that owns it
Dead automations Firing or lurking, unknown Retired, proven dead first
Governor limit pressure Eleven automations per save Two, with headroom
Onboarding a new admin Reverse-engineer the black box Read one flow per object
Same business behavior, expressed two ways after the audit and consolidation.

Here is how I pay down an automation stack

Paying down automation debt
  1. 1

    Inventory everything into one table

    Every flow, process, workflow rule, and trigger with object, trigger type, active status, last-modified date, and fields read and written. Pull from Tooling and Metadata APIs. The table is the artifact that ends the black box.

  2. 2

    Classify into dead, duplicated, load-bearing

    Dead references gone fields or can never fire. Duplicated overlaps another on the same save. Load-bearing does unique work. Every automation lands in exactly one bucket.

  3. 3

    Prove the dead bucket is dead, then retire

    Confirm zero fires in a real window of debug logs before switching anything off. "Looks unused" is not "is unused." Deactivate first, delete after a safe interval with no fallout.

  4. 4

    Consolidate duplicates into one artifact per object

    Fold the overlapping automations into a single before-save and single after-save flow with ordered branches. Behavior-test the consolidated flow against the originals before you retire them.

  5. 5

    Fold load-bearing logic in, do not orphan it

    The unique work joins the consolidated flow rather than staying a standalone artifact. The end state is one flow per object per timing that a new admin can read top to bottom.

  6. 6

    Govern new additions so the pile does not regrow

    A rule that new automation extends the existing flow for an object rather than adding a parallel one, plus the inventory kept current, is what stops you rebuilding 282 in five more years.

Nobody decided to build 282 automations. The org got there one reasonable “just add a flow” at a time, because the debt made editing feel dangerous and adding feel safe, and that incentive compounds until a lead save fires eleven things and no one dares change any of them. Paying it down is not a rewrite; it is an audit that makes the whole visible, a classification that separates the dead from the load-bearing, and a consolidation that expresses the same behavior in a fraction of the artifacts. We took 282 to 82 with nothing broken, because every cut was proven safe first. The governor at the end is what matters most: without a rule that new work extends the existing flow instead of adding a parallel one, you will rebuild the pile. The discipline that prevents the regrowth is the same declarative-first, one-flow-per-object pattern and the documented firing order that keeps the stack legible in the first place.

salesforce automation technical-debt

Keep reading

One email. Every week.

One email a week: a systems problem I architected or untangled, with the schema, the config, and what I would change. No roundups, no theory, unsubscribe whenever it stops being useful.

The newsletter opens soon.

Connect a provider in src/config.ts