Going Bare in Production

I walked into a codebase once that had been alive for seven years. It had
everything. A custom dependency injection framework built before DI containers
were standard. A hand-rolled caching layer wrapping the framework's own
caching layer. Three different patterns for the same database query, each
from a different year. And a four-thousand-line utils.cs.
The team was frustrated. Deployments took forty minutes. Onboarding took
months. The instinct was always to add. A new abstraction to tame the old
ones. A faster cache to fix the slow one. More code to solve problems caused
by too much code.
That was the lesson I keep relearning. The answer is almost never more. The
answer is almost always less.
There is a principle in systems theory called Gall's Law. John Gall wrote it
in 1975. A complex system that works is invariably found to have evolved from
a simple system that worked. A complex system designed from scratch never
works and cannot be patched up to make it work. You have to start over with a
working simple system.
It is not a suggestion. The working complex things you admire did not start
complex. They started simple and grew through iteration. Systems designed
complex from day one either died quietly or became the legacy you curse at
today.
Gall's Law implies something he did not state outright but every experienced
engineer knows. If a working complex system must come from a working simple
system, then the way to fix a struggling complex system is not to add to it.
It is to subtract until it becomes simple again.
Most engineers get the sequence wrong. When a system is slow or painful, the
reflex is to optimize. Add a cache. Add a queue. Add another abstraction. But
optimization should come last. Three steps come first.
Step one. Question the requirements. Not which department created them, but
which person asked for them. Go back to that person and ask: do you still
need this? You will be surprised how often the answer is no. Requirements
survive long after their reason has vanished. A feature for a customer who
left three years ago. A validation rule for a regulation that was repealed.
An integration two teams maintain because each assumed the other still needed
it.
Step two. Remove unnecessary parts. Look at every component, every
abstraction, every service. Ask whether it earns its place. You will find
patterns that exist because someone read a blog post five years ago. Code
that works around framework bugs fixed two major versions ago. Abstractions
that exist because it is the way it has always been done. None of these
deserve to stay.
Step three. Only now do you optimize. Only now do you think about
performance, cost, and scale. Because you are optimizing a system that is as
small as possible while still solving the real problem. You are not spending
cycles making dead code faster.
Step four is optional. By the time you reach it, there may be nothing left to
scale.
This sequence sounds simple. It is not. Removing is psychologically harder
than adding. Adding feels productive. Adding shows up in sprint reviews.
Removing feels like admitting a mistake. But the engineers who build systems
that last are the ones who get comfortable with subtraction.
In 2026, this matters more than ever. AI coding tools generate code faster
than anyone can read it. They churn out abstractions, patterns, and
workarounds in seconds. But they never question requirements. They never ask
whether the code should exist at all. They add. They always add.
"Vibe coding" describes the practice of prompting an AI, accepting the
output, and moving on without understanding it. The result is comprehension
debt at a scale we have never seen. Codebases are growing faster than ever,
and most of what gets added is dead on arrival. Patterns that made sense for
someone else's problem. Abstractions that solve a constraint that does not
exist here. Complexity for its own sake.
The subtraction-first engineer is the antidote. In a world where anyone can
add code at the speed of thought, the scarce skill is knowing what to remove.
The scarce skill is tracing a requirement back to its human source and asking
whether it still matters. The scarce skill is looking at a thousand-line pull
request and spotting the eight hundred lines that do not belong.
Antoine de Saint-Exupéry wrote in 1939 that perfection is achieved not when
there is nothing more to add, but when there is nothing left to take away. He
was writing about airplane design. The principle holds for every system
humans build. The best engineers I have worked with do not write the most
code. They delete the most code. They walk into a seven-year-old codebase,
find the four-thousand-line utils file, and delete three thousand lines
without breaking anything. Then they deploy, and somehow everything is
faster.
Before your next optimization, before your next clever abstraction, ask
yourself one question. What can I remove first? The answer might be more than
you think. And the result might be better than you imagined.
Disclaimer: All content reflects my personal views only and does not represent the positions, strategies, or opinions of any entity I am or have been associated with.


