The most valuable decision your team makes leaves no artifact. Here’s how to give it one.
Two engineers, two pull requests, same week.
The first is 50 lines. It solves the problem, ships in two days, and causes zero incidents over the next six months. The second is a pub/sub system with an abstraction layer and a configuration framework. It takes three weeks. It also works.
Six months later you’re writing promotion packets. The 50-line PR gets one line: “Implemented feature X.” The pub/sub system gets a paragraph: “Designed and implemented a scalable event-driven architecture, introduced a reusable abstraction layer later adopted by two other teams.” That paragraph reads like a Staff+ case. The 50-line PR was the better engineering.
It’s tempting to call this a values problem. Some engineers over-build because they never learned restraint. That’s part of it. Most of it is something else.
Teams reward complexity because they can see it.
Nobody means harm. The problem is what gets measured, and you don’t fix a measurement problem by telling people to try harder.
(The two-engineers setup comes from “Nobody Gets Promoted for Simplicity” on terriblesoftware.org. This post borrows it and adds the part that matters to a manager: what to do about it.)
Simplicity leaves no artifact
The 50-line fix leaves nothing to point at. There’s no design doc, no architecture diagram, no story about other teams adopting it. The three-week system has all three. Everywhere you measure engineers, the elaborate version is easy to see and the simple one is not:
- Interviews. The simple correct answer gets challenged (“what about ten million users?”). The complex diagram gets a nod. Candidates learn fast that elaborate impresses.
- Design reviews. Someone asks “shouldn’t we future-proof this?” and the engineer adds layers for requirements nobody has yet.
- Promotions. Elaborate systems give you a story to write. Simple ones give you a line.
Engineers aren’t confused. They respond to what gets rewarded. If complexity shows up in the packet, you’ll get complexity.
The same article quotes Dijkstra: “Complexity sells better.” He wasn’t being cynical. He was describing the incentive.
Earned vs. unearned complexity
Complexity itself isn’t the problem. What matters is whether it was earned.
| Type | Trigger | Example |
|---|---|---|
| Earned | A real, present constraint | ”We’re hitting database limits. We need to shard.” |
| Unearned | A hypothetical future one | ”We might hit database limits in three years. Let’s shard now.” |
Earned complexity is the job. Unearned complexity looks like the job. It seems responsible and scalable. The user doesn’t get the feature any sooner, though, and the next engineer has to learn abstractions nobody needed.
Default to simplicity. Complexity has to justify itself against a constraint that exists today.
Nobody gets promoted for the incident that never happened
You can’t lecture a team out of an incentive structure. You can change what the structure measures. Here are four levers:
Credit the rejected approach. Judgment is invisible until someone writes it down. “Evaluated an event-driven architecture and a custom abstraction layer; a straightforward implementation met every requirement” records the same engineering work as building them. Put it in the PR description. Put it in the packet.
Ask one question in every design review, before anyone says “shouldn’t we future-proof this?”: what’s the simplest version we could ship, and what specific signal would tell us we need more? The question makes complexity carry the burden of proof.
Celebrate deletion out loud. When someone removes code or says “we don’t need this yet,” name it in the retro and in the channel. That tells the team what gets rewarded. They pay more attention to it than to your values doc.
Push on impressive-sounding systems in calibration. Ask: “Did the problem actually require this?” A packet that reads like a technology showcase should prompt that question before anyone signs off.
None of this is subtle, and it doesn’t need to be. Simplicity is invisible, so you have to write it down where people can see it.
Why this is a manager’s job
One engineer can’t change this default alone. If the room rewards complexity, building complexity is the rational move, and personal taste rarely survives a promotion cycle that pays for the opposite. The team sets the default, so the leader has to own it.
It also costs money. Viktor Cessan’s “The Economics of Software Teams” puts a number on it: a team has a real daily cost, and most orgs can’t see it. Three weeks of unearned complexity on a feature that serves two percent of users has a price. You pay the salaries, you lose the work that didn’t happen, and every future change pays to route around it. Put that way, “keep it simple” is a cost decision.
Agents make the same mistake faster
This matters more now that coding agents write code.
Agents have read a huge amount of enterprise architecture. They’ll copy it into a feature that needed 50 lines: abstraction layers, a pub/sub bus, a config framework for a single use case. That’s unearned complexity at machine speed. The design-review question catches it here too: what’s the simplest version, and what signal would tell us we need more? Encode it in the plan and review gates when you run agents like a team. The judgment is the same when the author is a model. The complexity just arrives faster. On an uneven team running agents, the default matters even more, because the over-building compounds across every session.
Give the invisible decision an artifact
“Nobody gets promoted for the complexity they avoided.” That stays true until you make the avoided complexity visible.
Take the most valuable decision your team makes, the one that leaves nothing to point at, and give it something to point at. Write down the judgment. Reward the restraint out loud. Set the default at the team level, where defaults get set.
Then your best engineers no longer have to choose between doing the right thing and getting credit for it.