Summary: "Unknown unknowns are the bane of software architecture." After five years of shipping code that passed review and reached production, the author opened real architecture books and saw a rear-view mirror full of silent mistakes — retries with no backoff or idempotency, anemic domain models, trusting a database's default isolation level without knowing which anomalies it prevents. None were sloppy; all passed review, because the blind spot belonged to the whole team, not one person. The lesson: choose a technology for the problems it introduces, not the promises it makes.

The blind spots that shipped with a green checkmark

The mistakes weren't careless work that slipped past the process — they passed review, approved line-by-line by senior engineers and tech leads whose whole job is to catch exactly this. They couldn't see it either. Concretely: getters and setters on everything because every Java codebase around did it; anemic domain models with all business logic in one fat service (a Transaction Script in everything but name); trusting PostgreSQL's default isolation level without understanding which anomalies it prevents; retries with no backoff, no jitter, sometimes no idempotency. Each choice felt reasonable — which is exactly what made it dangerous. Without idempotency or backoff, a retry loop doesn't soften an outage; it amplifies it.

The mirage of "company practice"

Beginners assume that if a practice is standard inside a big-name company, it must be correct — so they copy, paste, and apply the existing patterns. But "what we take for standards of excellence are often just compromises made by teams under time pressure, normalized by the years." A team can run for years on a flawed pattern simply because the conditions that would trigger the failure never line up. That isn't engineering — that's luck. The trap compounds because we're wired for hype: a shiny framework or seductive pattern shows up, we see only the promises and the fast setup, roll it out everywhere, and discover the side effects a year or two later when the system is under load and drifting out of sync.

Every solution is tomorrow's problem

Software engineering isn't a linear science where you solve a problem once and move on — it's a chain reaction. The more skills you grow, the harder the problems you take on; the more problems you solve, the more new ones you uncover, because every solution carries its own trade-offs. Those trade-offs don't show up right away — they wait for the system to grow, for load to climb, for some unimagined use case to surface three years later. "Architecture is the art of choosing, today, which problems you agree to deal with tomorrow."

The knowledge quadrant

The author leans on a model any reader of Building Evolutionary Architecture will recognize — three tiers of knowledge:

  • Things you know — your comfort zone, the stacks you've mastered.
  • Things you know you don't know — you know Raft or Paxos exists even if you've never implemented one; you can go read up when the day comes.
  • Things you don't know you don't know — the real danger zone. Total blind spots: concurrency and network edge cases you don't even suspect can exist.

That third tier is where most of his own mistakes came from. "You can't weigh the trade-offs of idempotency if you've never heard the word. You can't reason about write skew if nobody has told you it's a thing." The scary part was never making the mistakes — it was not knowing they were mistakes. This is the practitioner-scale version of the same danger Architecture Has a Set of Secret Problems. Other Professions Solved Theirs names at the profession scale: an untested claim and a tested one look identical when both just have a name.

The new lens: choose your problems

His decision process flipped. Now it runs in two strict steps: first, a quick skim of the upside — does it solve the exact problem I have today? Then the only step that matters — the trade-offs. He goes digging through docs, post-mortems, and theory for the part nobody puts on the landing page: What breaks? How does it behave when the network fails? What happens when the message broker goes down? What does it really cost to maintain? Seeing a retry library, the first questions are no longer "great, more reliability" but "what if the operation isn't idempotent? if ten thousand clients retry in the same instant? if the dependency is already drowning?" — the feature didn't change, the questions did. "I don't choose a technology for its promises. I choose it for the problems it introduces — the ones I'm willing to live with."

Being wrong is the only real way to learn

Finding out that code you wrote six months ago was flawed isn't a failure — it's proof you've grown. "A developer who looks at their code from two years ago and still finds it perfect is a developer who learned nothing in 24 months." Technique you learn from books; resilience you earn by studying your own mistakes. The books didn't make him an architect — they taught him to stop assuming he could already see the whole map.