On this page
- The short answer
- What actually breaks between one and twenty
- The Shared Spine
- The arithmetic of a portfolio
- One exception queue, one envelope
- Migrations are the real cost at portfolio scale
- Tier the portfolio, because uniform standards are unaffordable
- Retrofitting the spine without a migration project
- Decommissioning, the discipline nobody has
- The vocabulary, used precisely
The short answer
The automations do not break as you add more of them. The things between them break. Automation one is a project and automation twenty is a platform, and the difference is a shared substrate: one secrets store, one retry and dead-letter convention, one run log with a correlation id, one exception queue, one model alias layer, one eval harness, one cost ledger. Build that spine at automation three, when it costs a week. At fifteen it costs a quarter, plus a migration nobody wants to fund, plus the incidents that happen while you do it.
- 7 partsin the shared spine, and there is a natural order in which you will need them
- autos x depsmigration work scales with how many automations touch each shared system, not with the automation count
- 20 channelsof exception alerts equals zero attention. The mute button is the honest metric
- Last human actionthe decommission signal, because a workflow can run green forever and produce output nobody opens
- Alias, not model idone indirection that turns a provider deprecation from twenty rewrites into one config change plus evals
The uncomfortable part is that nothing goes wrong at automation four. The costs accumulate quietly and present themselves around automation ten as a general feeling that the team has slowed down, which nobody can attribute to anything specific. This guide is about what is actually accumulating and what to build before it does.
What actually breaks between one and twenty
Seven things degrade, and they degrade in a predictable order. None of them is a bug in any individual automation, which is why reviewing each automation on its own finds nothing wrong.
- Credential sprawl. Twenty automations carry perhaps forty credentials across a dozen vendors, created by different people at different times with no register and no expiry dates. The first symptom is an outage traced to a token nobody knew existed.
- Alert fatigue. Each automation's alerting is individually reasonable. Collectively it produces enough noise that somebody mutes a channel, and the mute is permanent. Count the muted channels, because that number is your real alerting coverage.
- Exception attention collapse. One automation posting exceptions to a channel gets read. Twenty channels get read by nobody, and the backlog becomes visible only when a customer asks about something from three weeks ago.
- Coupling to shared systems. If nine automations write to the CRM, a field change in the CRM is nine regressions and nine conversations. The cost driver is automations per dependency, and it is invisible until the dependency moves.
- Knowledge concentration. The person who built the first eight becomes the routing table for every question. Their calendar is the constraint on the whole programme, and no dashboard shows it.
- Convention divergence. Each automation was built with the tool that felt right that quarter. On-call now cannot debug the ones they did not build, so incidents route by author rather than by availability.
- Cost opacity. One bill arrives with no attribution. Nobody can answer what automation twelve costs per month, so nobody can decide whether it is worth keeping, and every conversation about spend becomes a conversation about the total.
Notice that six of the seven are shared-resource problems. Only knowledge concentration is about people, and even that is mostly a symptom of convention divergence. Standardise the shape of an automation and the bottleneck person stops being the only one who can read the code.
The Shared Spine
Seven pieces of shared infrastructure, listed in the order you will need them. The automation numbers are ordering rather than thresholds: a portfolio of three high-volume customer-facing systems needs the eval harness sooner than ten internal reports do.
The Shared Spine
Build each piece once, for the portfolio, at roughly the point where the pain first appears. Every one of them is a week of work early and a quarter of work late.
Needed by automation two. Every automation authenticates as itself with a credential named after it, held in one store with owners and expiry dates. Without this, credential archaeology becomes a recurring project and revoking anything is dangerous because nobody knows what else uses it.
Needed by automation three. Same policy, same jitter, same dead-letter destination, same rule about which operations are safe to retry at all. Twenty bespoke retry loops mean twenty different behaviours during an upstream outage, several of which will amplify it.
Needed by automation four. A single id generated at the trigger and carried through every system the work touches. Without it, answering what happened to this specific invoice means opening four tools and matching timestamps by eye, which is how a fifteen minute question becomes an afternoon.
Needed by automation five. Every automation writes exceptions in the same shape to the same place, with a dedupe key and a severity defined by consequence. This is the highest return item on the list, because it converts twenty ignored channels into one queue with an owner and an age alarm.
Needed by automation six. Prompts versioned in the repository, model references made through internal aliases rather than provider ids written into twenty files. The alias layer is three lines of indirection that will save you an entire migration.
Needed by automation eight. Not per automation, per task type: classification, extraction, drafting, routing. A shared harness means a model change is one command that reports what moved, instead of a judgement call made by whoever is least busy.
Needed by automation ten. Tag every model call, every vendor call and every compute unit with the automation id, and produce a monthly line per automation. Without attribution, cost conversations happen at the portfolio level, where the only available decision is to stop doing all of it.
The decision that costs the most is letting each automation pick its own tool, its own retry behaviour and its own alerting. It feels efficient at the time because each choice is locally optimal, and it produces a portfolio that only its authors can operate. Pick the shape at automation two, write it into a template repository, and accept that a slightly worse tool used consistently beats a slightly better one used once. This is the same trade-off discussed in choosing between n8n, Make and custom code, applied to a portfolio rather than a single build.
The arithmetic of a portfolio
Two terms drive portfolio maintenance and only one of them is obvious. Incident load scales with the number of automations. Migration load scales with the number of automations multiplied by how many of them touch each shared dependency, which is why consolidating on fewer shared systems reduces work more than reducing the automation count does.
Every input is yours. The full-time equivalent divides by 1,680 productive hours a year, an assumption you should replace with your own. Migration means anything that forces you to touch several automations at once: a provider deprecation, an API version change, a schema change in a shared system.
Run it twice. Once with your current numbers, then again with the incident minutes halved and the migration hours halved, which is roughly what the spine buys you: shared retry behaviour and a real exception queue cut resolution time, and an alias layer plus a shared eval harness cut migration time. The gap between the two runs is the payback, and it is usually large enough that the argument for building the spine stops being a matter of taste. For the model side of that bill, costing an agent before you build it covers the per-run arithmetic.
One exception queue, one envelope
This is the single highest return piece of the spine, and it is a schema rather than a product. Every automation writes exceptions in one shape to one place. A human opens one view, sorted by severity and age, and every row carries enough context to act without opening the system that produced it.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "exception_envelope",
"description": "Every automation in the portfolio writes exceptions in this shape, to one queue.",
"type": "object",
"required": ["correlation_id", "automation_id", "occurred_at", "severity",
"category", "dedupe_key", "suggested_action", "payload_ref"],
"properties": {
"correlation_id": {
"type": "string",
"description": "Follows the unit of work across every system it touches. Generated at the trigger, never regenerated downstream."
},
"automation_id": {"type": "string"},
"run_id": {"type": "string"},
"occurred_at": {"type": "string", "format": "date-time"},
"severity": {
"enum": ["s1_customer_visible", "s2_work_blocked", "s3_needs_a_human", "s4_informational"],
"description": "Defined by consequence, never by exception class. A timeout is not a severity."
},
"category": {
"enum": ["upstream_unavailable", "auth_failed", "schema_mismatch",
"low_confidence", "policy_block", "unhandled_input", "budget_exceeded"],
"description": "Closed list. Adding a value is a pull request, which keeps the taxonomy usable."
},
"dedupe_key": {
"type": "string",
"description": "Stable across repeats of the same underlying cause, e.g. sha256(automation_id + category + upstream_host). One outage becomes one row with a count, not four thousand rows."
},
"occurrences": {"type": "integer", "default": 1},
"first_seen_at": {"type": "string", "format": "date-time"},
"suggested_action": {
"type": "string",
"description": "Written by the author at build time, when the failure is understood. Not by the on-call engineer at 2am, when it is not."
},
"runbook_url": {"type": "string"},
"payload_ref": {
"type": "string",
"description": "A pointer into your own store, never the payload itself. Keeps personal data out of the queue and keeps rows small."
},
"retry_state": {"enum": ["not_retryable", "retrying", "exhausted", "dead_lettered"]},
"owner_hint": {"type": "string", "description": "From OWNERS.yaml, so routing survives a reorganisation"}
}
}
- The dedupe key is what makes the queue usable. One upstream outage produces thousands of exceptions with a single cause. Hash the automation, the category and the upstream host into a stable key, collapse repeats into one row with a count, and the queue stays readable during exactly the incident when you need to read it.
- Severity is defined by consequence, never by exception class. A timeout is not a severity. A timeout on a payment confirmation and a timeout on a nightly report are two different events, and only the consequence tells you which is which.
- suggested_action is written at build time. The author knows what to do about a schema mismatch on the day they handle it. The on-call engineer at 2am does not, and asking them to work it out from a stack trace is how a five minute fix becomes an hour.
- Store a pointer, not the payload. Personal data does not belong in an alerting queue, and rows containing whole documents make the queue slow and expensive. Keep a reference into your own store with the same retention rules as the source.
- Alert on queue age, not queue size. A thousand informational rows are fine. One severity two row that is six hours old is not. Age is the metric that correlates with harm, which is the point covered further in error handling that stops silent failures.
Migrations are the real cost at portfolio scale
A single automation experiences a provider change as an afternoon of work. Twenty automations experience it as a project, and the difference is entirely down to whether you built the indirection layers early. Here is the same set of events priced both ways.
| What changes | Without the spine | With the spine | The piece that does the work |
|---|---|---|---|
| A model you depend on is deprecated | Find every hardcoded model id, change each one, then guess whether output changed | Repoint one alias, run the golden set, fix only the prompts that regressed | Model alias layer plus shared eval harness |
| A shared prompt pattern needs a fix | Twenty near-copies, edited by hand, several missed | One versioned prompt, one pull request, evals prove the change | Prompt registry |
| An upstream API adds a required field | Discovered as production failures, one automation at a time | One integration client raises one failure, fixed once | Shared client library and correlation id tracing |
| A credential is compromised | Nobody knows which automations use it, so revocation is a gamble | The register names every consumer, rotation is scheduled with overlap | Secrets store with service identities |
| A vendor changes pricing | The total moves and nobody can say which automation caused it | The per-automation line shows exactly which ones became uneconomic | Cost ledger with attribution |
| An eval threshold has to move | A judgement call by whoever is least busy that week | A threshold change in one config, with the regression report attached | Shared eval harness |
Keep an internal alias such as extraction-default that maps to a provider model id in exactly one config file, and have every automation reference the alias. Deprecation timelines, context limits and prices all change on the provider's schedule and not yours, so check their own deprecation notices for dates rather than trusting any figure written in a guide, including this one. The alias is what turns that external schedule into a change you control the timing of.
Tier the portfolio, because uniform standards are unaffordable
Applying critical-system discipline to all twenty automations is expensive enough that it will be abandoned, usually within a quarter, and abandoned unevenly. Tier them instead, write the tier into the manifest, and make the tier decide the alerting, the review cadence and the eval requirement.
The tier also decides how much of the spine an automation is obliged to use. Tier one uses all of it. Tier three needs the secrets store and the exception queue and can skip the eval harness entirely. Being explicit about that is what stops the standard from being quietly ignored, because a rule that is expensive and universal gets broken silently, while a rule that is proportional gets followed. Ownership obligations follow the same tiering, as set out in who owns the automation after launch.
Retrofitting the spine without a migration project
You almost certainly cannot get a quarter funded to refactor working automations, and you should not ask. Retrofit on contact instead. The portfolio converges within a couple of quarters and no single change is large enough to need approval.
- Inventory everything in one day
One row per automation: trigger, systems touched, credentials used, owner, tier, last change, last human action on its output. Do it in a spreadsheet. The inventory alone usually finds two automations nobody can account for.
- Pick the piece with the most current pain
Usually the exception queue or the secrets store. Choose by which one caused your last two incidents, not by which is most interesting to build.
- Wire the newest automation to it first
The newest has the fewest users and the freshest code, so it is the cheapest place to find out that your envelope schema is missing a field. Fix the design there before anything else depends on it.
- Retrofit on touch, never in a batch
Any automation you open for another reason gets moved onto the spine before you close it. Make it a rule in code review. This is the whole trick, and it works because you were already paying the cost of loading that system into your head.
- Set a hard date for new work
After a stated date, no new automation ships outside the template repository. Enforce it in the template rather than in a document, so the compliant path is also the fastest path.
- Sweep the stragglers, and turn off what the sweep finds
Whatever has not been touched in two quarters is either stable or dead. The inventory column for last human action tells you which, and the dead ones should be decommissioned rather than migrated.
Decommissioning, the discipline nobody has
At twenty automations, some of them are dead and still running. They execute perfectly, cost money every month, appear in every migration, and produce output nobody has opened since the person who asked for it changed jobs. Execution metrics cannot see this, because the automation is working exactly as built.
Instrument consumption, not just execution. Track the last time a human acted on the output: opened the file, viewed the report, replied to the message, touched the record downstream. That single field turns the decommission conversation from an argument about opinions into a query. Then retire with a tombstone rather than a delete: disable the trigger, keep the definition and the documentation, leave a note where the output used to appear, and wait thirty days. If nobody complains, delete it properly and remove its credentials. If somebody does complain, you have just found an owner who did not know they were one.
The vocabulary, used precisely
- Correlation id
- A single identifier generated when a unit of work is triggered and carried unchanged through every system it touches. It is what makes the question of what happened to this particular record answerable in one query rather than four tools.
- Exception envelope
- A shared schema that every automation uses when reporting an exception, carrying severity, category, a dedupe key, a suggested action and a pointer to the payload. It is what makes one queue readable across a whole portfolio.
- Dedupe key
- A stable hash of the underlying cause of an exception, so that thousands of repeats from one outage collapse into a single row with a count. Without it, a queue becomes unreadable during the incident it exists to surface.
- Model alias layer
- An internal name mapped to a provider model identifier in exactly one configuration file, referenced by every automation. It converts a provider deprecation from a code change in many places into one config change plus an evaluation run.
- Portfolio tier
- A classification that decides how much discipline an automation is obliged to carry: alerting behaviour, review cadence, evaluation requirement and ownership depth. Tiering exists because uniform critical-system standards across a whole portfolio get abandoned.
- Tombstone
- Retiring an automation by disabling its trigger while keeping its definition, documentation and a note where its output used to appear, then deleting properly after a waiting period. It makes decommissioning reversible and therefore politically possible.
The honest summary is that the twentieth automation is not twenty times the work of the first, and it is not the same work either. It is a different job with a different bottleneck, and the teams that stall are the ones that keep treating each new build as a project rather than as another tenant on shared infrastructure they have not built yet. Build the spine early, tier the portfolio so the standards are affordable, and instrument consumption so the dead ones leave. Business process automation at this scale is mostly infrastructure and ownership work, and very little of it is prompting.
ChatGPTalker, "Scaling from One Automation to Twenty" (2026). What breaks as an automation portfolio grows is the shared substrate, not the automations. Build the shared spine at automation three: secrets and service identities, a retry and dead-letter convention, a correlation id, one typed exception queue, a model alias layer, an eval harness, and a cost ledger with per-automation attribution.
Questions readers ask next
At what point should we build shared automation infrastructure?
Do we need a dedicated platform team for twenty automations?
Should every automation use the same tool?
How do we know which automations to turn off?
What is the most common mistake when scaling an automation programme?
How do we handle a provider deprecating a model across twenty automations?
ChatGPTalker. "Scaling from One Automation to Twenty: What Changes." chatgptalker.com, 2026-08-26. https://chatgptalker.com/guides/scaling-from-one-to-twenty/