Earned Complexity

John Gall said it well:

A complex system that works is invariably found to have evolved from a simple system that worked.

Sounds simple enough. And it keeps showing up because it keeps being true.

Why the big design fails

The temptation is always the same. You understand the problem well enough to see the full shape of the solution. So you design the full shape. You account for the edge cases, the future requirements, the scaling concerns. You draw the architecture diagram and it looks right. Clean boxes, clean arrows.

Then you build it, and things start to slip. Not because the diagram was wrong exactly, but because the diagram couldn’t contain what it needed to. The real constraints - the ones that determine whether the thing actually works - only reveal themselves when the system is running. How users actually use it. Where the load actually lands. Which assumptions were quietly wrong.

A design is a prediction. The more complex the design, the more predictions it contains, and the more places it can be wrong in ways you can’t see from the whiteboard.

What the simple system knows

A simple system that works has something a design document can never have: contact with reality.

Every piece of it has been tested by actual use. The messy parts, the ad-hoc parts, the things that look like they should be cleaned up - those are often load-bearing in ways that aren’t obvious from the outside. They accumulated through a thousand small corrections, each one a response to something real.

The web started as a document-sharing hack at CERN. Tim Berners-Lee built the simplest thing that could work - HTML, URLs, HTTP - and shipped it. No grand vision for e-commerce or social media or streaming video. Each of those emerged later, growing from a foundation that had already proven it worked. The complexity is enormous now, but every layer earned its place by being added to something that was already running.

The rewrite trap

Rewrites aren’t always a bad idea. But they’re tricky in a specific way. You look at the old system and see a mess. You look at the new design and see clarity. But the mess contains knowledge the design doesn’t. This is what drives the second-system effect — the rewrite tries to fix everything v1 got “wrong,” and in doing so throws away everything v1 got right.

I’ve done this. The old service was ugly - inconsistent naming, weird special cases, code paths nobody fully understood. The new design was beautiful. Clean abstractions, proper separation of concerns, everything accounted for. Months later, the old system was still in production because the new one kept hitting problems the old one had quietly solved years ago.

The wrong abstraction often looks better than the working mess. That’s what makes it so tempting. The mess is illegible - hard to explain, hard to diagram, hard to hand to a new hire. The clean design is legible. It fits on a slide. But legibility and effectiveness aren’t the same thing.

Growing instead of designing

The systems I’ve seen work best weren’t designed to handle what they handle now. They started small - often embarrassingly small - and grew in response to real pressure. Each piece of complexity was added because something actually broke or something was actually needed, not because someone anticipated it on a whiteboard.

That’s a different kind of complexity than the kind you get from a big upfront design. Designed complexity is speculative. Grown complexity is earned. You can feel the difference when you work in the codebase. One has layers that exist for reasons nobody remembers. The other has layers where you can trace each one back to a real problem.

This is hill-climbing applied to architecture. And hill-climbing has a known blind spot - it finds the top of whatever hill you’re on. You can grow a beautifully evolved system that solves the wrong problem. Starting simple doesn’t save you from building the wrong thing. It just means you find out sooner.

Simple isn’t always better. But simple is where working systems start. The complexity comes later, and it comes honest.