2.2.3 · D5Design Principles

Question bank — YAGNI — You Aren't Gonna Need It

1,951 words9 min readBack to topic

Before we start, one shared vocabulary reminder (every answer below leans on it):

Now let's earn the decision rule instead of quoting it. Look at the two roads a speculative feature can take.

Figure — YAGNI — You Aren't Gonna Need It

The next figure shows why, in real software, the left side almost never clears the right side.

Figure — YAGNI — You Aren't Gonna Need It

True or false — justify

The trap here is that each statement sounds obviously right or wrong. Force yourself to name the mechanism.

Adding an empty "extension hook" now is basically free because it's only 5 minutes of typing.
False. The 5 minutes is ; the real bill is — every future reader, test, and refactor must respect that hook forever, and it shapes designs around an imaginary requirement.
YAGNI tells you to skip input validation on a public endpoint until users complain.
False. Validation protects a present requirement (security/correctness), so it is needed now. YAGNI defers speculative future features, never today's non-functional needs.
If a feature has a high probability of being needed exactly as imagined, YAGNI still forbids building it.
False. When is genuinely high, can exceed and the inequality is satisfied — then building now is justified. YAGNI is a bet against low- speculation, not a blanket ban.
YAGNI and KISS — Keep It Simple say the same thing.
False. KISS says "make the thing you do build simple"; YAGNI says "maybe don't build the thing at all yet." One shapes the how, the other questions the whether.
Applying DRY — Don't Repeat Yourself the instant you see two similar lines of code is good discipline.
False. Abstracting on the first duplication is speculation about a future third case — that violates YAGNI. Wait for the Rule of Three: the third real occurrence.
YAGNI means "no architecture, just hack the minimum."
False. YAGNI forbids speculative features and abstractions, not clean design, tests, or boundaries that serve present needs. Architecture for today's requirement is not speculative.
Because is usually smaller than building now, deferring is often the cheaper path even if the feature does get built.
True. Later you build against a real requirement instead of a guess, avoiding wrong-shape rework — so for the design that's actually correct.
Deleting speculative code you already wrote is a waste, so you might as well keep it.
False. Sunk cost is gone either way; keeping it means paying daily for zero benefit. Removing dead speculation is a saving, not a waste.
Premature Optimization is a completely different mistake from YAGNI violations.
False. It's the same disease — speculation — in a performance flavor: optimizing for a load you only imagine, paying complexity now for uncertain future gain.

Spot the error

Each item states a reasoning move someone actually makes. Name the flaw precisely.

"We'll definitely switch from PostgreSQL someday, so I built a backend parameter accepting mongo/mysql/s3."
The word "someday" with no ticket means is tiny while the abstraction is carried forever (). When a real switch comes you'll refactor anyway — and you'll finally know the actual interface needed.
"I added retries, priority, and schedule params to send_welcome_email — notifications obviously need them eventually."
Every unused parameter is untested surface area paid for now. "Obviously eventually" is a guess, not a requirement; extract a Notifier only when a second real channel (e.g. SMS) actually arrives.
"We duplicated the tax calc in two places, so I immediately pulled out a TaxStrategy interface to stay DRY."
Abstracting on the second occurrence bets on a third that may never come — premature DRY that violates YAGNI. The Rule of Three says wait for the third real case so the abstraction fits reality.
"YAGNI says build the minimum, so I dropped the auth check on our new admin endpoint."
Confuses speculative features with present non-functional requirements. Auth on an admin endpoint is needed now; YAGNI targets imaginary future features, not today's security.
"The feature is only used once but I'll keep the generic plugin loader we built — removing it feels destructive."
This treats sunk as a reason to keep paying . The correct comparison is future cost only: an unused generic loader is pure ongoing debt with no asset.
"We logged our forecast that we'd need multi-tenant support in Q2; Q2 came and it wasn't needed, but the code's already there so it's fine."
The forecast failing is exactly the evidence YAGNI predicts (low ). "Already there" means you're now paying for a guess that came out wrong — remove it.

Why questions

These probe the mechanism — the part people skip.

Why is , not , the real reason speculation is expensive?
is paid once, but is paid continuously — every read, test, and refactor for the whole life of the code — while delivering nothing until (and unless) the guess comes true.
Why is building later often cheaper than building the same feature speculatively now?
Later you have the real requirement in hand, so you build the correct shape once. Speculative-now guesses the shape, and wrong guesses force rework, making the true cost higher.
Why does the YAGNI inequality usually fail in real software?
Requirements drift so is small, is charged every day, and is modest — so the certain right-hand cost typically outweighs the small probable benefit.
Why is speculative code described as "Technical Debt with no asset"?
Normal debt buys you something today; speculative code is pre-paid effort and ongoing carry cost that buys you nothing unless an uncertain future arrives — debt whose asset column is empty.
Why does YAGNI hand off to the Rule of Three instead of just saying "never abstract"?
YAGNI defers abstraction until it's justified by real cases; the Rule of Three gives the concrete trigger — the third genuine occurrence — so you abstract on evidence, not on a guess.
Why can keeping a "just in case" config flag actually constrain future design?
Once the flag exists, every new feature must respect its branches, and refactors must preserve behavior for a path nobody uses — the imaginary requirement quietly shapes real decisions.
Why did Extreme Programming pair YAGNI with strong testing and refactoring rather than up-front design?
Because if changing code later is cheap and safe (tests + refactoring), there's no need to guess ahead — you can confidently defer decisions until requirements are real.

Edge cases

The boundaries where "just apply YAGNI" breaks down. Know exactly which side of the line each falls on.

A change would be irreversible later (e.g. a public API contract or a stored data format). Does YAGNI still say "defer"?
Weaker here. When later change is genuinely expensive/irreversible, is huge, so a modest amount of forethought can be justified — YAGNI's math tilts toward doing more now when deferral is truly costly.
The feature is a legal/compliance requirement that "kicks in next year." Speculative or present?
Effectively present: a dated, contractual obligation gives and a real deadline, so it's a known requirement, not a guess — build it when the timeline demands, not "never."
Two call sites already need the same behavior today. Does DRY-now violate YAGNI?
No. Removing existing, present duplication is DRY doing its job on real cases. YAGNI only forbids abstracting for a hypothetical future third case.
A performance path is currently too slow and users are affected now. Is optimizing it "premature"?
No — it's a present requirement, not speculation. Premature Optimization is optimizing for imagined future load; fixing a measured, current bottleneck is just meeting today's need.
You genuinely can't tell whether is high or low for a proposed abstraction. Default action?
Default to not building it. Uncertainty means the certain cost () is real while the benefit is unproven — and deferring keeps the cheap option () open.
A tiny, self-contained helper "might" be reused, and extracting it costs almost nothing to carry. Build it?
Borderline, and here YAGNI is soft: if (trivial, isolated, no design constraint imposed), the inequality is easy to satisfy. The danger is underestimating carry cost — most "free" abstractions aren't.
Your forecast log shows you were right about a feature 3 predictions ago. Does one hit disprove YAGNI?
No. YAGNI is an expected-value rule over many decisions; occasional correct guesses are expected. The log's value is showing that most predictions miss, keeping realistically small.

Recall One-line summary to carry away

YAGNI is not "do less" — it's "spend certain cost only on present requirements, and let uncertain futures pay for themselves when they arrive." Every trap above is a case of mistaking a guess for a requirement, or a present need for a speculative one.

Connections

  • YAGNI — You Aren't Gonna Need It — the parent principle and its cost model.
  • Rule of Three — the trigger YAGNI defers abstraction to.
  • DRY — Don't Repeat Yourself — removes existing duplication; don't confuse with speculation.
  • KISS — Keep It Simple — simplify what you build; YAGNI questions whether to build.
  • Premature Optimization — the performance-flavored twin of the same speculation trap.
  • Technical Debt — speculative code is debt with an empty asset column.
  • Extreme Programming — the methodology that pairs YAGNI with testing and refactoring.
  • Simplicity — the shared north star.