Definition:
Engineering Complexity is the study of what makes software hard to build, understand, and change — and the discipline of minimizing it. It distinguishes between two fundamentally different kinds of complexity: essential complexity (the inherent difficulty of the problem you’re solving) and accidental complexity (the difficulty you create for yourself through poor design, wrong tools, or unnecessary abstractions).
The core insight — first articulated by Fred Brooks in “No Silver Bullet” (1986) — is that essential complexity cannot be eliminated (the problem is what it is), but accidental complexity is entirely our own creation and we have an ethical obligation to minimize it.
═══════════════════════════════════════════════════════════════
THE TWO KINDS OF COMPLEXITY
═══════════════════════════════════════════════════════════════
┌─────────────────────────────────────────────────────────┐
│ │
│ TOTAL SYSTEM COMPLEXITY │
│ ─────────────────────── │
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ │ │
│ │ ACCIDENTAL COMPLEXITY │ │
│ │ ───────────────────── │ │
│ │ │ │
│ │ Complexity WE CREATE ourselves: │ │
│ │ │ │
│ │ • Over-engineering — "let's use microservices │ │
│ │ for a blog" │ │
│ │ • Wrong abstractions — leaky layers that │ │
│ │ need constant workarounds │ │
│ │ • Framework lock-in — fighting the framework │ │
│ │ instead of solving the problem │ │
│ │ • Inconsistent patterns — everything is done │ │
│ │ 3 different ways │ │
│ │ • Premature optimization — caching before │ │
│ │ you measure │ │
│ │ • Boilerplate — code that has to exist but │ │
│ │ doesn't solve the problem │ │
│ │ │ │
│ │ ❌ CAN and SHOULD be minimized │ │
│ │ │ │
└─────────────────────────────────────────────────────┘ │
+ │
┌─────────────────────────────────────────────────────┐ │
│ │ │
│ ESSENTIAL COMPLEXITY │ │
│ ──────────────────── │ │
│ │ │
│ Complexity INHERENT to the problem: │ │
│ │ │
│ • Piloting a 747 — must handle aerodynamics, │ │
│ weather, weight distribution, air traffic │ │
│ • Processing payments — must handle currency │ │
│ conversion, fraud detection, compliance, audit │ │
│ • Hospital system — must handle patients, │ │
│ staff, drugs, billing, regulations, emergencies │ │
│ │ │
│ ✅ CANNOT be eliminated — only managed │ │
│ │ │
└─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
Example:
═══════════════════════════════════════════════════════════════
HOW COMPLEXITY KILLS ENGINEERING ORGANIZATIONS
═══════════════════════════════════════════════════════════════
THE COMPLEXITY TRAP:
┌─────────────────────────────────────────────────────────┐
│ │
│ Stage 1: "Let's just add this one service..." │
│ Stage 2: "...and deploy it in its own K8s cluster" │
│ Stage 3: "...and a message queue for communication" │
│ Stage 4: "...and a cache layer for performance" │
│ Stage 5: "...and a monitoring stack to track it all" │
│ Stage 6: "...and a platform team to manage the │
│ platform" │
│ Stage 7: "...and a second platform team to manage │
│ the first platform team" │
│ Stage 8: Silence. Nobody ships features anymore. │
│ Everyone is "managing complexity." │
│ │
└─────────────────────────────────────────────────────────┘
THE REALITY DISTORTION:
“We need Kubernetes to manage our containers.” → We have 3 containers. A docker-compose.yml works fine.
“We need microservices for team autonomy.” → We have 2 teams. A modular monolith works better.
“We need eventual consistency for scalability.” → We have 500 users. Strong consistency works at any scale.
“We can’t move fast without this abstraction.” → You moved slower building the abstraction than you would have without it.
“We need [complex tool] because we’ll need it later.” → You are guessing. Build for what you have. YAGNI.