Our services

If you can think it, we can make it brainsoft.

How to estimate a software project without overpromising

Written By: BrainSoft In Engineering

Most bad estimates are not bad math. They are bad scope. Somebody asks for a date, someone else sketches a number in a meeting, and six weeks later the team is explaining why the "simple" integration with a legacy ERP has consumed the whole sprint. The estimate was never the problem. The problem was that nobody wrote down what the estimate assumed.

Estimate in ranges, not single numbers, and make the assumptions visible. Break the work down until each piece is small enough to reason about, put a confidence level on each piece, add explicit buffers for unknowns and dependencies, and hand the client a document that says what would have to be true for the low end to hold. That is the whole method. The rest of this article is how we actually do it.

Break the work down before you put a number on it

A single line item called "user management" is not an estimate, it is a wish. Split it until each task is something one person could finish in a day or two and describe in one sentence. If you cannot describe the task without saying "and then some stuff happens", it is still too big.

For each task, write down three numbers: the best case if nothing goes wrong, the likely case, and the worst case you would actually accept. The gap between best and worst is your uncertainty, and it is information, not weakness. A task with a 2x spread needs a spike or a conversation with the client before you commit to anything.

We keep the breakdown in a plain file next to the repo so it lives with the code and can be diffed when it changes:

## Stripe webhook handling
best: 0.5d  likely: 1d  worst: 2d
assumes: webhook secret already provisioned in staging
risk: retry/idempotency edge cases if events arrive out of order

## PDF invoice export
best: 2d  likely: 4d  worst: 8d
assumes: template approved by client before dev starts
risk: font embedding, pagination for long line items

Turn the breakdown into a range the client can read

Sum the likely numbers for the baseline, sum the best for the optimistic end, and sum the worst for the pessimistic end. Then add a separate contingency line for things you know you do not know yet, such as third-party API behaviour, data migration quality, or sign-off speed. Contingency is not padding hidden inside tasks. It is its own visible line, and the client should see it.

  • Give a range, never a single date, at least until the discovery phase is done.
  • State the confidence: what percentage chance is there that the work fits in the range?
  • List the assumptions in the same document, numbered, so they can be confirmed or rejected.
  • Call out dependencies on the client side, like access, approvals, content, and test data.
  • Say what happens if an assumption turns out to be false, in terms of time and cost.

A sentence like "4 to 7 weeks, assuming the legacy API returns JSON and not screen-scraped HTML" is honest and useful. "5 weeks" is a coin flip dressed as a plan. If you need help turning a rough idea into a scoped estimate, get in touch and we will walk through the unknowns with you.

Handle the unknowns explicitly instead of quietly

Some uncertainty cannot be estimated away. When a task depends on how a system behaves, and nobody on the team has seen that system, a time-boxed spike is cheaper than a guess. Two days of investigation that produces a written finding is a better deal for everyone than a three-week overrun later.

We also separate discovery from delivery in the proposal. Discovery has a fixed price and a fixed duration because we control it. Delivery is estimated as a range because it depends on what discovery finds. Clients accept this when you explain it plainly, and the ones who do not are usually the ones who will argue about every change order.

Track actuals against the estimate from week one. If the first two tasks come in at twice the likely number, the rest of the plan is wrong and you should say so early, while there is still room to adjust scope. Silent overruns destroy trust faster than an uncomfortable conversation.

What not to do

  • Do not estimate under pressure in a sales call. Say you will come back with a range.
  • Do not pad every task by 30 percent and hope. Hidden padding gets eaten and nobody learns anything.
  • Do not estimate work you have not broken down, even if the client wants a number today.
  • Do not treat the low end of the range as the commitment. It is the best case, and best cases rarely happen.
  • Do not skip the QA, deployment, and handover tasks. They are real work and they belong in the estimate.

The goal is not to cover yourself. It is to give the client a number they can plan around, with the conditions attached. Our our services page covers the kinds of projects where this matters most, but the method works for any size of engagement.

Frequently asked questions

Why not just give the client a fixed price?

You can, once the scope is stable and the unknowns are resolved. Before that, a fixed price is either padded heavily or a promise you may not keep. We offer fixed pricing for discovery and for well-understood phases, and ranges for the parts that depend on findings.

How wide should the range be?

It should reflect the real uncertainty. A well-understood feature might be plus or minus 20 percent. A new integration with a system nobody has inspected can easily be 2x. Narrowing the range artificially to look confident is the mistake, not the width itself.

What happens when the estimate turns out to be wrong?

We say so as soon as we know, show the actuals against the estimate, and propose options: reduce scope, extend the timeline, or change the approach. The earlier that conversation happens, the more choices everyone has.


#Engineering