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.
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.
View as table
| Point | Value |
|---|---|
| Y1 | 40 |
| Y2 | 95 |
| Y3 | 160 |
| Y4 | 230 |
| Y5 | 282 |
| After | 82 |
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.
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 |
Here is how I pay down an automation stack
- 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
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
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
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
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
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.
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