How do you decide what to build with limited engineering?

When engineering capacity is tight, the decision of what to build is itself a product decision. The right answer is almost never 'build less'—it's 'build the right thing completely.' That means a short list, clear user outcomes tied to each item, and nothing on the roadmap that isn't directly connected to a problem a real user has right now.

Constraints force elegance, not compromise

Paul Graham's observation in his essay on taste is that a tight budget or a difficult site forces an architect toward elegance—fashions and flourishes get knocked away by the hard business of solving the problem at all. The same is true for engineering. A two-person team that tries to build twelve features ships twelve half-finished things. A two-person team that builds two features completely—edge cases, error paths, regression tests—ships something users can actually rely on.

This reframes the question. You're not asking 'which features can we squeeze in?' You're asking 'which one or two problems, if solved completely, change whether this product is worth using?' Everything else is deferred, not canceled. The constraint is the filter.

The trap founders fall into is confusing roadmap length with ambition. A long backlog feels productive. But shipping something half-baked trains your users to distrust the product and trains your team to accept incomplete work as the norm. A shorter list with higher completion standards produces compounding returns: trust, retention, and a codebase you can actually move fast on.

Tie every build decision to a specific user outcome

Garry Tan's engineering philosophy, visible throughout his gstack project, centers on one discipline: tie technical choices to what the real user sees, loses, waits for, or can now do. This is not a values statement—it's a filtering mechanism. If you can't finish the sentence 'a user who has this problem will now be able to…' for a proposed feature, you don't have enough clarity to build it yet.

In practice this means writing the user outcome before writing a single line of code. Not a user story in Jira format, but a plain description: who is blocked, what they can't do, what they'll be able to do when this ships, and how you'll know it worked. Features that can't survive that exercise are usually premature abstractions—solutions to problems you imagined rather than observed.

This discipline is especially important when engineering capacity is limited because ambiguity is expensive. Every hour spent building the wrong interpretation of a vague requirement is an hour that can't be spent on the thing that actually matters. The spec work—clarifying exactly what changes for exactly which user—is not overhead. It's how you avoid wasting the engineering hours you do have.

AI compression changes the math, but not the judgment call

The practical reality of building in 2025 is that certain categories of engineering work have gotten dramatically faster. Boilerplate, scaffolding, test writing, and routine feature implementation can be compressed by 10x to 50x with the right AI-assisted workflow. This doesn't mean you have unlimited capacity—it means the bottleneck has shifted from typing code to making decisions about what to build and how to structure it.

For a small team, this has a concrete implication: the work that used to require a specialist (writing a full test suite, scaffolding a new service, handling error paths) no longer justifies skipping it. The excuse 'we don't have time to write tests' evaporates when test writing takes fifteen minutes instead of a day. What remains scarce is architecture decisions, product judgment, and the willingness to do the complete thing rather than just the demo path.

So when you're deciding what to build, the question isn't just 'do we have the engineering hours?' but 'do we have the judgment to specify this well enough to execute it?' A poorly specified feature will waste time regardless of how fast your execution is. Clear thinking about the problem—root cause, desired outcome, edge cases—becomes the true rate limiter.

A practical method: outcome-first prioritization

Here is a concrete process you can run in an afternoon. Take every item on your build list. For each one, write three things: the specific user problem it solves, the measurable signal that tells you it worked, and what happens to your users if you don't build it in the next ninety days. Items where the third answer is 'nothing changes' go to the back of the queue immediately.

For everything that survives, estimate completeness cost honestly. A feature that takes two days to build the happy path but four additional days to handle edge cases and error states is a six-day feature. Shipping the two-day version is not shipping at half cost—it's shipping something that will erode trust every time a user hits an edge case. Garry Tan's framing is useful here: know the difference between a 'lake' (completable in the current sprint) and an 'ocean' (a multi-quarter migration). Build lakes completely. Don't start oceans you can't finish.

After this exercise, a backlog of twelve items usually compresses to two or three that are genuinely urgent, two or three that are important but not time-sensitive, and a long tail that was wishful thinking. Ship the urgent ones completely. Schedule the important ones with honest timelines. Archive the tail without guilt—you can always pull something back if user feedback changes the picture.

“A difficult problem could be good for a designer, but a fickle client or unreliable materials would not be.”

— Paul Graham, source

The one thing to do

Write the user outcome before you write any code—if you can't finish 'a user who has this problem will now be able to…', you're not ready to build it yet.

Frequently asked questions

How do you say no to a feature request from an important user?

Name the tradeoff explicitly: 'If we build this, we delay X by three weeks.' Let the user help you decide rather than pretending the constraint doesn't exist. Most users will accept a clear tradeoff; what they can't accept is being told no without understanding why.

Should a small team build infrastructure or features first?

Build the feature first, then extract the infrastructure if multiple features need it. Infrastructure built in anticipation of future features almost always ends up solving the wrong problem. Wait until you have two or three concrete use cases before abstracting.

How do you handle pressure from investors or advisors to build more?

Show them the completion standard, not the feature count. A product with three deeply functional, reliable features is more fundable than a product with twelve half-built ones. Frame velocity in terms of outcomes shipped, not tickets closed.

When is it worth slowing down to pay technical debt?

When the debt is causing you to ship broken things to users or when it's measurably slowing down every new feature you build. Debt that only bothers the engineering team internally is lower priority than debt that reaches users.

Sources

More playbook answers · Growth Prophet home