Skip to content
Back to blog

The Hidden Cost of Features: Why I Say No More Than I Used To

5 min read
ProductEngineering CultureStartupCareer

Early in my career, saying yes was my competitive advantage. New feature? Yes. Quick addition for that one client? Yes. Can we squeeze it into this sprint? Yes. I shipped fast, people were happy, and I genuinely believed velocity was the whole job.

Seven years and several startups later, I say no, or more precisely, "not like this," more than ever. Not because I got slower or more precious. Because I finally understood what a feature actually costs, and almost none of that cost is the build.

The price tag nobody writes down

When a feature is estimated, the number on the ticket is the construction cost: three days, two weeks, whatever. Here is what is not on the ticket:

The maintenance annuity. Every feature is a small recurring payment, forever: dependencies to upgrade, edge cases to patch, behavior to preserve through every refactor. A feature built in three days and kept alive for four years was not a three-day feature. I have maintained "quick wins" whose cumulative upkeep exceeded their build cost several times over.

The surface-area tax on everything else. Each feature makes every future feature slightly more expensive. More states to consider, more interactions to test, more migration paths to preserve. This compounds quietly. The codebase where shipping took two days in year one and two weeks in year four did not get worse engineers, it accumulated surface.

The combinatorial trap. The worst offenders are features that multiply against each other. Permissions x export formats x notification preferences: each was reasonable alone; together they created a test matrix nobody fully covers and bugs that only appear for the one customer using all three. When I evaluate a feature now, the first question is not "how long to build?" but "what does this multiply with?"

The deletion problem. Code is easy to add and politically expensive to remove. The feature used by 2% of accounts cannot be killed because one of them is a flagship logo. I have seen products carry years of this, a long tail of barely-used capability that constrains every redesign. Shipping is reversible in theory. In practice, almost nothing ships with a return policy.

The focus cost. The subtlest one. Every feature claims a slice of the team's mental model and a slice of the user's. Products do not usually die from missing features. They die bloated: slow to change, hard to learn, impossible to position.

What changed in how I work

The shift was not learning to refuse things. It was changing what I ask before building. A few that earn their keep:

"What happens if we don't build this?" Shockingly often, the honest answer is "the client grumbles and adapts" or "we lose a deal we would have lost anyway." If the no-build scenario is survivable, that is the bar the feature has to beat, including all its hidden costs, not just its build estimate.

"Can we buy the learning cheaper?" Half the features I get asked to build are actually experiments wearing a feature costume: someone wants to know whether clients would use X. An experiment can be a concierge process, a fake door, a spreadsheet and a Slack channel. Build the learning, not the feature. If the learning says yes, then build the feature, properly.

"What's the smallest version that's still honest?" Not an MVP that does everything badly, but a deliberate scope cut that does one thing completely. The discipline is writing down what is explicitly out, so the cut is a decision rather than an accident the support team discovers.

"Who maintains this in 18 months?" If the answer is "nobody specifically," the feature is an orphan at birth. Orphan features are where production incidents go to be born.

And one behavior change that mattered more than any framework: putting the hidden costs in the conversation, in writing, at decision time. Not to block, but to price. "We can do this; here's the build, here's the maintenance bet, here's what it multiplies with, here's what we're not doing instead." It is remarkable how many feature requests evaporate when their true price is visible, and how much better the surviving ones are.

The freelancer's version of this problem

As a freelancer, this gets sharper, because saying no appears to contradict the business model: I am literally paid to build. But the incentive actually points the other way. A consultant who builds everything asked of them delivers a heavier product and a thinner result, and the client eventually notices which one they paid for. The clients who came back, in my experience, are the ones I talked out of something.

The deliverable a senior engineer brings is judgment with code attached. Anyone can produce the code part now, and that is increasingly literal, given what agents can generate. What cannot be generated is the moment someone looks at a roadmap and says: this line right here will cost you triple what it says, and this other line should not exist.

What I would tell myself at the start

Velocity is the most legible thing about an engineer, so early on you optimize for it. I did, and it was probably right at the time. But the engineers I have learned the most from were not the fastest builders. They were the best refusers: people who could see the four-year cost of a three-day ticket and say so, kindly, with numbers, before the yes was given.

Features are loans. Build velocity is how fast you can borrow. And the teams that move fastest in year four are the ones that borrowed carefully in year one.

Working on a similar AI project? Let's talk about it.