1 · The word
“It’s a complex system.”
I’ve heard that sentence used as an explanation, and I’ve heard it used as a shield, and I’ve stopped being sure I can tell the two apart from the outside.
It comes up when someone explains why a release takes nine months. It comes up in job descriptions. It comes up when you ask why two teams own the same process and nobody has merged them. A lot of processes, a lot of data, a lot of stakeholders, a lot of regulation. All of that is usually true. But somewhere in there the sentence stops describing the situation and starts excusing it. Why improve something that’s already working? It’s complex. Changing it would take a long time.
A word that can end any conversation isn’t doing much work. And I think “complex” has quietly become that word in a lot of product organisations. It’s the thing you say when you’d rather not look.
Before that sounds like I’m pointing at other people: I’ve used it exactly the same way.
“I’m good at complex systems” is on my CV. It’s in how I describe what I do, and I’ve said it in more interviews than I’d like to count. At some point somebody asked me what I actually meant by it, and I gave an answer I didn’t fully believe, because I was assembling it live, and I had never written it down.
That’s an uncomfortable thing to notice about a claim you’ve been making for years. It’s also, as far as I can tell, currently the most-claimed and least-evidenced line in senior product design. Everyone says it. It signals almost nothing.
And it matters more than it did a few years ago, because we’ve started handing this work to tools that will confidently do whichever version of “complex” you point them at, and never ask which one it was.
So this is me working out whether I mean anything by it, starting with the question I should have been able to answer in those interviews. Complex compared to what, and which kind?
2 · Which kind
Here’s the set of distinctions I ended up with. I didn’t get them from a framework. I put them together while I was researching this piece, which means they aren’t authoritative and I don’t think they’re complete. The first two are a plain-language version of a distinction Dave Snowden formalised in the Cynefin framework. The other three I assembled from reading and from work.
There’s a lot of it. Many entities, many rules, many states. Nothing surprising in any single one; there are simply a lot. A pricing model with four hundred valid configurations is like this. So is a permissions system with nine roles. This kind is hard work but it isn’t mysterious: you can sit down with the people who know, write it all out, and get it right. The failure mode is skipping that and guessing.
The parts interact in ways nobody listed. This is the genuinely different one. The trouble doesn’t come from any single rule. It comes from a combination nobody wrote down, because nobody thought of it. You find these in production. And the failure mode is the opposite of the first: you can’t analyse your way out, and a beautiful specification will not save you. What you need is room to be wrong cheaply.
Those two get confused constantly, and it’s expensive in both directions. Treating a knowable system as unknowable means running experiments instead of asking the domain expert who’s been sitting two desks away for six years. Treating an unknowable system as knowable means writing a very confident document and then meeting reality.
Rules that come from outside. Regulation, compliance, contractual terms, a standard you have to certify against. You can’t negotiate these and you can’t design them away. What you can do is find them early, because they’re the constraints most likely to invalidate a design after it’s been built.
People. Many stakeholders with genuinely different positions. Not because anyone is being difficult, but because the compliance officer and the sales lead really do want different things, and each is right about their own half. This is the kind most often dismissed as a soft problem, which is a mistake. It’s where decisions actually get made, in places the org chart doesn’t show.
Time. The system has a history and the history is still running. Legacy data, half-finished migrations, three versions live at once, a decision from 2019 nobody can explain that everything depends on. Almost nothing is greenfield.
Most products have several of these at once, in different proportions, and that’s fine. You don’t have to decide which one your product is. The point is that when someone says “this is complex,” the useful next question is which kind, and I have almost never heard anyone ask it.
3 · The reflex we’re trained on
Whichever kind of complexity you’re facing, the first instinct is nearly always the same: simplify.
That instinct is usually right, and it’s most of what makes design valuable. But I’ve come to think it’s also the low-hanging fruit, the easiest thing to reach for when you’re facing something big. You look at complexity and go straight to: how do we cut this down, how do we make it simpler? Simplicity becomes the principle leading your actions, instead of reserving the time and the place to understand what the core of that complexity actually is, and which kind you’re touching.
There’s an idea from cybernetics, published in 1956, that says this doesn’t work the way we think it does.
W. Ross Ashby was a psychiatrist who ended up more or less inventing the field, and he wrote a line I’ve been thinking about since I found it: “Only variety can destroy variety.” Anything regulating a system needs at least as many available responses as the system has possible states. With fewer, it isn’t regulating the system. It’s just present while the system does what it wants.
In product terms: if the domain admits forty valid configurations and your interface offers six, you haven’t simplified anything. You’ve lost control of thirty-four of them. They don’t disappear. They come back as support tickets, as workarounds that quietly become load-bearing, as long email threads.
And most often, they come back as documents.
Not one document. A spreadsheet somebody in operations maintains. A note in a private folder. A wiki page nobody links to. An email thread that turns out to be the only record of a decision. None of it official, all of it scattered, and it exists because the product cannot hold something the business genuinely needs to be true: the pricing exceptions, the customers on legacy terms, the approval rules nobody built.
The scattering is the dangerous part. Sometimes the person who wrote one has forgotten it exists. When they leave, something breaks, and nobody is quite sure what.
I’ve come to think of that pile as a measurement. It’s the exact amount of complexity the product refused to carry, written down by hand by the people who ended up carrying it instead.
This corrected something in my own thinking. I used to list progressive disclosure as a complexity strategy. It isn’t, quite. Progressive disclosure sequences variety. It decides what order you meet it in. It never reduces the amount. Hiding complexity and sequencing it are different jobs, and it took me a while to notice I’d been calling them the same one.
It’s worth separating the three things we all call “simplifying.”
Hiding. The variety leaves the screen and lands on a person. You remove options from the UI, and support handles those cases by email. You add a smart default that guesses, and the user who needed the other option finds a workaround. The variety went somewhere. It went to someone.
Sequencing. The variety stays, and arrives in an order. Progressive disclosure, honestly used. A flow that asks questions in dependency order rather than importance order. Role-based views, where a technician sees their subset and an admin sees everything. Total variety preserved, partitioned by who needs which part.
Actually reducing it. You can only do this by changing the domain rather than the interface. Deleting a feature nobody uses. Merging two overlapping approval processes into one. This is the only one of the three that genuinely lowers the amount.
And notice that none of it happens in a design tool.
4 · Tesler’s question
So if you mostly can’t reduce it, and what you’re really doing is moving it around, the honest question is where you’re moving it to.
Larry Tesler asked exactly that, around 1984, at Xerox PARC and then Apple:
“Every application has an inherent amount of irreducible complexity. The only question is: Who will have to deal with it—the user, the application developer, or the platform developer?” Larry Tesler · The Law of Conservation of Complexity
It usually gets used as an economic argument: let the platform absorb the complexity, because one team pays that cost once while millions of users would otherwise pay it every day.
Worth knowing that this reading isn’t Tesler’s. His own page states the law and stops there. The economics come from people interpreting it afterwards, and he links to some of them. It’s a fair reading and a real argument, and it isn’t the one I’m making. I’d rather say that than pretend I hadn’t read it.
What I keep returning to is the structure of the question. Three places the complexity can go, and Tesler is clear that it goes to one of them. Here’s how I’d translate that to a product organisation today:
The user, and the support function standing behind them. Complexity shows up here as tickets, workarounds and shadow spreadsheets. It’s the easiest one to miss, because from the outside the product looks simple.
The product team. Designers, PMs, the engineers building the feature. Complexity shows up as longer specs, more branches, more edge cases, a growing list of known issues, and releases that slip.
The platform team. Whoever owns the things every other team builds on: the design system, the API layer, the internal tooling. Complexity shows up as more primitives, more configuration surface, and a heavier foundation every other team inherits whether they asked for it or not.
I found that list slightly uncomfortable to read, because I’d written it myself without knowing. My own way of describing what I do is that a design system is a constraint system for the UI layer, a domain model is a constraint system for the product layer, and a team topology is a constraint system for the org layer. Three floors. It’s Tesler’s three bearers with different names on them, and I got there by working rather than by reading.
When the answer is “the product team carries it,” that is not an abstraction. That’s somebody’s evenings, and more often it’s somebody’s attention. The spec that took three weeks instead of one. The release that slipped. And the version I recognise from my own work: being the person who holds all the use cases in their head, tired less from the hours than from the number of things you can’t put down, because the rule that mattered was never written down and you were the one who remembered it.
I have no interest in the version of product work where the response to complexity is that everyone works harder. I’ve met the people who run things that way, and the logic is always the same: hours are the resource you spend when the system gets difficult, and speed is the only thing being optimised. I don’t think that’s ambition. I think it’s a distribution decision nobody made deliberately and nobody wrote down.
Sustainable isn’t a soft word here. It means the complexity is sitting somewhere that can hold it indefinitely, rather than somewhere that’s holding it because one particular person hasn’t burned out yet.
Which is why what comes next matters, and why I don’t think the answer is obvious. Tesler gave us three places to put the complexity. There is now a fourth.
5 · But should it exist at all?
Before I get to what the fourth one is, there’s a question that comes first, and it gets skipped almost every time.
Everything above was about what kind of complexity you’re facing. This is a different question: whether it should be there at all.
Fred Brooks made the distinction in 1986, following Aristotle: essence, the difficulties inherent in the nature of the thing, and accidents, those difficulties that attend its production but are not inherent.
Essential complexity comes from the problem itself. Insurance really does have that many product variants. Manufacturing configuration really does have those dependencies. You can’t design it away, and attempts to do so produce something that doesn’t work.
Accidental complexity is everything else. A data model that was wrong three years ago and everything is now built on top of. Two approval processes that overlap because two teams built them separately. An integration that survives because removing it is frightening.
Brooks was mostly writing about tools and representations. The version I meet most often is organisational: who approves what, which two teams don’t talk, which decision has three owners. That’s still accidental by his definition, because it attends production without being inherent to the problem. I’d argue it’s also the most commonly ignored kind, because it doesn’t look like a technical problem and so nobody files it as one.
Essential complexity you distribute. Accidental complexity you delete.
This test matters here rather than being a footnote, because of what happens when you skip it. If you decide who carries complexity without first asking whether it should exist, you can end up carefully distributing something that should have been deleted.
And that’s about to get much easier to do.
6 · The fourth bearer
Back to Tesler’s three: the user, the product team, the platform team. All three are people.
We’ve added a fourth, and I don’t think many of us decided to. It arrived as a productivity tool, and somewhere in the last two years it became a place we put work.
I’ll say plainly what I think and then spend the rest explaining why, because the claim on its own sounds more hostile than I mean it.
An AI agent, meaning a large language model doing work on your behalf, is the worst available owner of systemic complexity.
The reason has nothing to do with how good it is at the work.
The first half of that is about how much room you leave yourself.
There are two separate questions here, and they get mixed up constantly.
The first is how much can go wrong? That’s complexity. How many parts there are, and how many of them can affect each other in ways nobody planned.
The second is how much warning do you get? That’s coupling. How much room and time sits between one thing going wrong and the next thing going wrong.
The simplest version I know: a typo in a document you’re still drafting, and the same typo in an email that has already gone out. Identical mistake. Completely different amount of room.
You can barely change the first question. If a product has forty valid configurations, it has forty. You can almost always change the second, and the second decides whether a mistake costs a review comment or an incident.
Two versions of the same agent, differently coupled.
In the first, it opens a pull request and a person reads it before it merges. In the second, it commits straight to main. The capability is identical. The complexity is identical. What differs is the room between the mistake and the consequence: in one, a bad change costs a comment. In the other it costs a rollback, and possibly a customer noticing before you do.
Or take a design system token. You change a spacing value. In one setup every product picks it up automatically on the next build. In another, each product opts in when it next releases. Same change. In the first, if the value is wrong, three products are wrong before anyone looks at them. In the second, the first team to hit it tells you.
Both examples turn on the same variable: how much room you left.
And we keep choosing the tight version, because the loose one costs exactly the time the tool was bought to save. Notice where that decision sits. The model didn’t choose to be wired straight into production. A team did, under deadline. Which means a better model wouldn’t change it. This is the same distribution decision as before, made quickly, usually by default, and almost never written down.
7 · What the thing is actually like
That’s the room. The other half is the tool itself. Here is what the research says.
The standard way to test whether a model can find something in a large body of text is a “needle in a haystack” test: bury a fact in a lot of text and ask for it. Models score close to perfect, and it’s worth understanding why. The needle usually shares words with the question. A model can win by matching strings. The test looks impressive and tells you almost nothing about whether anything was understood.
A team fixed that with a benchmark called NoLiMa, published at ICML in 2025. Same idea, except the question and the answer deliberately share as little vocabulary as possible, so the model has to work out that they’re related rather than spot a match.
They tested thirteen models, all sold as supporting at least 128,000 tokens. At 32,000 tokens, which is a medium spec and a few files rather than some frontier edge case, eleven of the thirteen fell below half their own short-context score. GPT-4o went from 99.3% to 69.7%.
That’s the result that matters here, because of what it isolates. Systems work is never literal matching. The rule you need is never phrased the way you’d ask for it. The thing that breaks is precisely the thing they measured.
And this isn’t new, which is the part that makes it worth saying rather than just interesting. The same effect was first documented in 2023, on an entirely different generation of models. I wouldn’t lean on that paper on its own, because nobody should be citing 2023 model behaviour in 2026. What matters is that the property has survived three model generations and roughly a hundredfold increase in context window. That looks less like a bug awaiting a fix and more like a property of how these systems work.
And it isn’t the whole picture, which matters. A paper from February 2026 looking specifically at agents as their context grows found the same degradation, but also found that managing what goes into the context substantially improves the success rate. That’s real, and I rely on it every day.
There’s a catch inside it that took me a while to see. Context management means deciding what not to show the model. Which means somebody already has to know what’s relevant. The fix works by moving the judgement back to a person, which is the same move this whole essay is about.
8 · The bearer with no veto
So it degrades on exactly the kind of work that matters here, and we tend to couple it tightly. That alone would be reason enough to be careful. But there’s one more thing, and I think it’s the one that actually matters.
Go back to Tesler’s three. Every one of them can refuse.
The user refuses by not adopting the feature, working around it, calling support instead. The product team refuses by saying this spec contradicts itself, or we can’t maintain forty configurations, or that’s six months of work. The platform team refuses by saying that doesn’t belong in the platform.
Those refusals are inconvenient. They are also the only way an organisation ever finds out how much complexity it’s actually carrying. The friction isn’t in the way of the process. In a real sense it is the process, the measurement instrument itself. When a team pushes back on a spec, that’s the system reporting its own load.
I wrote about this from a different direction a while back, in The Friction AI Removes (and Why I Keep Putting It Back). That was about my own workflow. This is the same idea one floor up: friction in an organisation is information, and removing it without replacing the signal is how you stop knowing what’s happening inside your own product.
The fourth bearer doesn’t refuse. It complies.
I want to be precise, because the sloppy version of this claim is wrong and someone will rightly say so. Agents can absolutely detect problems. There’s good work on using them to find contradictions in requirements documents, and they’re genuinely effective at it. It isn’t that the thing can’t see complexity.
It’s that detection is not refusal. It will tell you there’s a contradiction if you ask it to look. It will not stop the work. It has no stake in maintaining what it produces, no Monday morning where it lives with the result, and no standing to say no.
And here’s the part I find most uncomfortable, which I’ll flag as something I think rather than something I’ve measured.
Remember accidental complexity, the kind you’re supposed to delete. Historically we deleted it because carrying it hurt. Somebody had to maintain that integration, work around that data model, remember that undocumented rule. The pain was the deletion pressure.
Take away the pain and you take away the pressure. Handing accidental complexity to an agent is the worst version of the whole mistake, because it makes the wrong thing cheap to maintain, and cheap things never get deleted.
9 · What to do instead
So if you can’t delete it, and you only get to decide who carries it, the next question is where you push.
Donella Meadows spent her career on systems, and in 1999 she published a list of twelve places you can intervene in one, ranked by how much difference each actually makes. It’s short, it’s free to read, and I’d put it above most product management writing.
Her point, the one that stung when I read it: “Leverage points are not intuitive. Or if they are, we intuitively use them backward, systematically worsening whatever problems we are trying to solve.” We push hardest on the places that move least.
Here is her list, weakest first, with what each one looks like in a product:
- 12Constants, parameters, numbers. A limit, a default, a price, a timeout, a line of copy.
- 11The size of buffers. Grace periods, draft states, retry allowances. How much slack before something breaks.
- 10The structure of stocks and flows. The data model. Which entities exist and how they relate.
- 9The length of delays. How long before someone learns they made a mistake. Inline validation, or an email two days later.
- 8The strength of balancing feedback. Error messages, validation, undo, confirmation.
- 7The gain on reinforcing feedback. Anything that compounds: recommendations, referrals, growth loops.
- 6The structure of information flows, meaning who does and does not have access. Permissions, visibility, dashboards, audit trails.
- 5The rules of the system. Incentives, punishments, constraints. What is allowed and what is forbidden.
- 4The power to self-organise. A team’s ability to change its own structure.
- 3The goals of the system. What the thing is actually for.
- 2The paradigm the system arises from.
- 1The power to transcend paradigms.
The reason I keep this list nearby is that it draws a line I can act on.
Most product design work lives at 12 through 8. That isn’t a criticism, those rungs need doing and doing them well is a craft. But 6 and 5, information access and the rules, are the highest points a product designer can realistically reach, and they’re the two that almost nobody owns. Everything from 4 upwards is strategy and above; claiming that ground would be overclaiming.
So the list is useful here for one specific reason. It tells you that the two rungs where complexity actually gets distributed are the two rungs nobody has put their name on.
That’s the same thing I’ve been describing the whole way through. When you decide the user carries the complexity, you have written a rule. When you decide the platform carries it, you have written a different rule. Deciding who carries it and setting the rules are the same job.
A few years ago I worked on mobile check deposit at Housecall Pro. Field service company, technicians in vans, and the feature let them deposit a customer cheque from their phone instead of driving it to a branch. It moved about $500,000 in deposits across roughly 2,500 transactions, and cut support tickets on that flow by around 80% just in the first month.
There were transaction limits. The obvious job was to design the limit: where the number appears, what the error says when you exceed it, how you ask for an increase.
I didn’t ship that. Not until role permissions existed.
A limit that isn’t attached to a role isn’t a limit, it’s a number on a screen. The technician and the business owner are different people with different authority, and until the system knew which was which, any limit I designed would have been a display of a rule that didn’t exist yet. In Meadows’ terms: changing the number is rung twelve. Writing a better error is rung eight. Deciding that limits are a property of a role is rung five. I held the feature until rung five existed, and that decision is the reason the tickets went away rather than moving somewhere else.
And this is where it connects back to the agent.
An agent is very good at the bottom of that list. It will change numbers, generate screens, rewrite copy, produce a hundred error states, faster than any team could. That’s real, and I use it for exactly that.
But Meadows’ warning is that intervening at low leverage feels productive and changes nothing. We have built something that does the low-leverage work a thousand times faster, and we are measuring it by how much it produces.
So what do you do about it. I don’t think the answer is use less of it. Two things, and neither is dramatic.
Know which rung you’re on. Most of the time you’ll be at twelve and eight, and that’s fine, because those rungs need doing. The mistake is being there while believing you’re somewhere else.
And leave yourself room. Everything above about coupling is a choice made once, quietly, usually by default: whether the output goes straight in, or whether something sits between it and production. It costs time. That’s the point of it.
10 · Where this doesn’t apply
I should say where this stops, because most products aren’t like this.
If you’re designing a landing page, a signup flow, a settings screen for a simple consumer app, none of this applies. The number of things that can interact is small, the cost of being wrong is low, and you can make it good and ship it. Reaching for a 1956 cybernetics law there would be completely unnecessary, and it would slow you down.
There’s a second boundary that’s more useful, and it’s Brooks again. If the complexity is accidental, if it’s there because of a data model that was wrong three years ago or two approval processes nobody merged, then the answer isn’t to distribute it carefully. It’s to delete it. Distributing accidental complexity is how a system calcifies around its own mistakes, and handing it to something that will maintain it cheaply and forever is the worst available version of that.
And the honest counter-argument, which is John Gall’s: complex systems that work almost always grew out of simple systems that worked. Systems designed complex from the start usually don’t. So if this essay makes you want to go and model everything before you build anything, I’ve made things worse rather than better. The point is knowing which rung you’re standing on.
11 · Close
I started this by admitting I’d been making a claim I couldn’t defend. So here’s the version I can defend, and it’s smaller than the one I used to imply.
I don’t think “good at complex systems” is a skill anybody has. What I can do is ask which kind of complexity is in front of me, decide where it’s going to sit instead of letting it settle somewhere by default, and write that decision down so the next person can find it. Three things, all boring, all checkable.
That’s less impressive than what the original claim implies. It’s also the part that survives being asked about.
Tesler’s question is still the right one, and I don’t think anyone has improved on it in forty years. Every application has an amount of complexity that can’t be removed. The only question is who deals with it. He gave three answers and every one of them was a person who could say no.
We’ve added a fourth, quickly, and mostly without deciding to.
I don’t think that means don’t use it. I use it every day, and the argument that it could carry the load so people don’t have to is a good one, which is why I wanted to take it seriously rather than wave it away. I think it means the friction we’ve spent two years trying to remove was doing a job, and it would be worth working out what that job was before we finish removing it.
Sources. Every link opened and checked on 25 August 2026. On complexity and where it goes: David J. Snowden & Mary E. Boone, A Leader’s Framework for Decision Making (HBR, 2007), where the complicated/complex distinction comes from. W. Ross Ashby, An Introduction to Cybernetics (1956), ch. 11 — “Only variety can destroy variety.” Larry Tesler, The Law of Conservation of Complexity. Frederick P. Brooks, Jr., No Silver Bullet (1986). Donella Meadows, Leverage Points (1999). Charles Perrow, Normal Accidents (1984) and John Gall, Systemantics (1975), both books with no open link. On what long context does to models: Modarressi et al., NoLiMa (ICML 2025); Liu et al., Lost in the Middle (TACL 2023); Zeng, Huang & He, LOCA-bench (Feb 2026, preprint). On finding contradictions: Automated requirement contradiction detection through formal logic and LLMs, Automated Software Engineering (2024) — paywalled; I’ve read the abstract and summaries, not the full paper.