The decisions that don't iterate

Most software people we admire ship fast. We do too. Every tool we have shipped moved from idea to released product in roughly the time you'd expect. The "ship fast and iterate" instinct is correct for the bulk of what a team builds.

But the same instinct, applied to the wrong decisions, is what most software regret turns out to be.

Some decisions iterate cleanly. You ship a version, watch how people use it, and adjust. The cost of being wrong is roughly the cost of one bad release.

Other decisions do not iterate cleanly at all. You ship them, they propagate through the system, and three years later you are still living inside the consequences with no good way out. The cost of being wrong there is the cost of every decision that came after, all stacked on top of the original mistake.

We have learned to identify three of these the hard way.

The first is schemas. The data model you ship in week one is the same data model your migration scripts will fight five years later. Every feature you build sits on top of it. Every report queries it. Every integration assumes it. You can rename columns, you can add tables, but the underlying shape of what you store and how is one of the hardest things in software to actually change. We sweat schema decisions in a way we do not sweat almost any other decision.

The second is interaction patterns. The first version of how a user does something becomes the version they remember. If your sign-up flow asks for a phone number before the user has seen anything useful, that is forever the way new users meet you, even after you change it. Power users will keep doing things the way they learned. Even your support docs will reflect the old shape, because that is what people are still confused about.

The third is early hires. The taste of the people you bring on in the first year is the taste that defines the product. They review every PR. They sit in every product review. They train the next set of hires. By the time you notice a hiring choice was wrong, the choice has already shaped the inside of the product in ways that take years to unwind.

These three share a property. They are not features. They are not decisions you ship and then learn from. They are conditions you set up, that everything else then operates inside of. Iteration is still happening. It is just happening inside a frame you have already drawn.

The trick is not to be slow. The trick is to know which decisions are inside the frame and which decisions are the frame.

We ship the inside-the-frame stuff fast. We are uncomfortable with the framing decisions. We make them once, we make them carefully, and we accept that we are going to live with whichever version we picked.

Ship fast. But know what you are shipping fast on.