Journal · The AI Architect · 2026-08-07
Restraint is the skill. Reach for the simplest thing that works, and make every added part earn its place.
Restraint is the skill. Reach for the simplest thing that works, and make every added part earn its place.
The tension isn’t simplicity versus complexity. It’s that complexity always shows up wearing the costume of diligence. Nobody adds a caching layer, a config flag, or a fourth microservice because they’re lazy. They add it because it feels responsible, thorough, professional. The hard part isn’t knowing that simple is better. Everyone knows that. The hard part is noticing, in the moment, that the thing you’re about to add is dressed up as necessity when it’s actually just insurance against a problem you don’t have yet.
Notice what you’re really buying
Every added part is a purchase, and the price isn’t paid upfront. It’s paid later, in the form of someone (often you, six months from now) having to understand why it’s there. A configuration option you added “just in case” is a small tax on every future reader of that code. A dependency you pulled in for one function is a promise to track its updates, its vulnerabilities, its breaking changes, forever, or until someone rips it out.
This is easy to say and hard to feel, because the cost is deferred and the benefit feels immediate. Adding the thing solves today’s discomfort: the nagging worry that you haven’t covered an edge case, the itch to make the system “more robust.” Not adding it requires tolerating that discomfort. Restraint, in practice, is mostly the skill of sitting with unfinished-feeling work without rushing to pad it out.
Try this: before adding anything — a library, an abstraction, a setting — write one sentence stating what breaks if you don’t add it. Not what improves. What breaks. If you can’t name a real failure, only a vague unease, that’s information. Put it aside and come back in a week. Most of the time you won’t remember why you wanted it.
Let the second instance write the rule
The other trap is generalizing too early. You write one function, then a second one that’s similar, and immediately your hands want to extract a shared abstraction, build a framework, make it “flexible.” But two examples aren’t enough to know what actually varies and what only looks like it varies. Premature abstractions tend to guess wrong, and then you’re stuck maintaining a general solution to a problem that turned out to be specific.
The simplest thing that works is usually the concrete thing, written twice, before it’s the abstract thing, written once. Duplication is cheap and honest. It says exactly what’s happening. Abstraction is a bet, and bets should be made with information, not hope.
Try this: the next time you feel the pull to make something generic, let it repeat a third time first. Copy-paste it again if you have to, even though it feels wrong. By the third occurrence you’ll actually see the shape of what varies, and any abstraction you build will fit the real problem instead of an imagined one.
Make the burden visible
Teams lose this skill not because they forget the principle but because the cost of complexity is invisible until it isn’t. Nobody feels the fortieth configuration flag as a burden on the day it’s added. They feel it eighteen months later, when a new engineer spends an afternoon trying to understand why the system behaves differently depending on three interacting settings nobody remembers the reason for.
Since the cost is invisible in the moment, you have to make it visible on purpose. This means treating “we added this” as a decision with a receipt, not a silent event. It means occasionally going back through what’s accumulated and asking, of each piece, plainly: is this earning its place right now, or did it earn its place once and we never checked again?
Try this: once a quarter, or once a project, list every configuration option, flag, or optional pathway in a system, and next to each one write who actually uses it and why. Anything you can’t answer for is a candidate for deletion. Deleting things that no longer earn their keep is not glamorous work, but it’s the maintenance that keeps the whole structure legible.
None of this is really about code, or even about software. It’s about the general discipline of noticing that more is not neutral, that every addition is a small mortgage on someone’s future attention, including your own. The instinct to add is natural and often generous — it comes from wanting to be careful, to cover the bases, to help. Restraint doesn’t mean caring less. It means aiming that care at the smallest thing that actually solves the problem in front of you, and being honest enough to admit when something you built out of caution never got used at all. The book goes further into how this plays out across design, teams, and the slow accumulation of technical debt — but the instinct itself, you can start practicing today, on whatever you’re working on right now.
Go deeper. The full method is in The AI Architect. New here? Start with the free companion pack, or explore the series.