Software estimation that survives contact with reality
Software estimation fails for a predictable reason: we estimate the work we can see and forget the work we can’t. The fix isn’t better guessing. It’s giving ranges instead of single dates, anchoring on how long similar work actually took, slicing work small enough to finish, and telling the business what the uncertainty is.
I’ve estimated software for two decades, including a software studio I co-founded that delivered 200+ projects for clients. These are the techniques that held up.
Why software estimates fail
Most estimates aren’t wrong because engineers are bad at arithmetic. They’re wrong for structural reasons that apply to every team:
- Unknown work. Integration quirks, edge cases, migrations, the config nobody documented. You can’t estimate what you haven’t discovered yet, and in new work it’s often the majority.
- Optimism bias. People picture the path where nothing goes wrong. Ask anyone how long a task takes and you get the best case, stated as the likely case.
- Skewed distributions. A task can finish a bit early, but it can run very late. Adding up “most likely” values across twenty tasks produces a total that is almost never hit.
- Pressure. When the first number someone hears is a date a sales lead already promised, estimates bend toward it.
- Scope moves. The thing delivered is rarely the thing estimated, and nobody re-estimates when scope changes.
Give ranges, not dates
A single number hides the most useful information: how confident you are. A range shows it. “Four to ten weeks” tells the business something real about risk that “six weeks” hides.
A practical form is three numbers per piece of work: the optimistic case, the likely case and the pessimistic case. Then communicate two of them: “very likely by X, possibly as early as Y.” If the gap between the two is wide, that’s the finding. It means there’s unexplored risk, and the right next step is to reduce it rather than to commit.
When someone insists on one date, give the date you’re confident in, not the one you’re hoping for, and say what would have to be true to beat it.
Use reference-class forecasting
Reference-class forecasting means estimating from how long similar things actually took, not from a breakdown of this particular thing. It’s the most reliable technique I know, and the least used.
Ask: “The last three times we built an integration with a third-party API, how long did it take from start to production?” If the answers were three, five and eight weeks, your new integration is probably in that range, whatever the task breakdown says. Then adjust for what’s genuinely different.
This needs history. Start recording, for every meaningful piece of work, the date it started and the date it shipped. After a quarter you have a reference class. After a year you have a forecasting tool better than any planning poker session.
Slice work until it’s boring
Large items are where estimation error lives. The fix is to slice them into pieces that each deliver something usable and each take no more than a few days.
Good slices are vertical: a thin path through the whole stack that works end to end. “Customer can save a draft invoice with one line item” is a good slice. “Build invoice database tables” is not; it can’t be shipped or tested on its own, and it hides the integration risk until the end.
- Split by workflow step: create, then edit, then delete.
- Split by rule: the happy path first, validations and edge cases as later slices.
- Split by data: one currency, then many; one user role, then all of them.
- Split out the risk: do the scariest unknown first as a spike with a fixed time box, so the rest of the estimate rests on facts.
Once work is sliced evenly, you can often skip estimating individual items and just count them. Throughput in items per week, multiplied out across the remaining items, is a forecast with surprisingly little error, and it costs no meeting time.
Story points, hours or counts?
Story points were meant to express relative size without implying a date. In practice they get converted into dates anyway, then into targets, then inflated. If your team uses them well, keep them. If they’ve become a negotiation, stop.
My default for small teams: estimate large initiatives as ranges in weeks using reference classes, slice them into small items, and forecast from item counts and historical throughput. Hours only make sense for short, well-understood tasks, and those rarely need estimating at all.
How to communicate uncertainty to the business
The business needs dates to plan launches, hiring and cash. Refusing to estimate isn’t an option. What helps is making the uncertainty visible and actionable:
- State the range and the confidence. “Eighty percent confident in eight to twelve weeks.”
- Name the top three risks and what you’re doing about each.
- Separate the fixed from the flexible. If the date is fixed, scope must flex. Agree which features are must-have and which can be cut.
- Re-forecast on a schedule. Every two weeks, with the range narrowing as work is done. Surprises in week nine are a process failure; a narrowing range is how you avoid them.
- Report early. Bad news at week three is a planning input. Bad news at week eleven is a crisis.
If your roadmap is a list of dates that keep slipping, the problem is upstream of estimation. A technology roadmap built around outcomes and confidence levels is easier to keep honest.
When estimates keep slipping anyway
Chronic slippage usually isn’t an estimation problem. It’s a symptom of interruptions, a slow review queue, or a codebase where every change touches everything. Those make throughput unpredictable, and no estimation technique can forecast an unpredictable system. I’ve covered the usual causes in why your engineering team is slow.
If a project is already months late and nobody trusts the next date, that’s a different situation: a software project rescue, where the first step is re-scoping to something that can actually ship.
Questions
Why are software estimates always wrong?
Because estimates cover the work you can see, while much of the real effort is work you discover along the way: edge cases, integrations and rework. Optimism bias and pressure push numbers lower still. Ranges, reference-class forecasting and small slices reduce the error considerably.
What is reference-class forecasting in software?
Estimating a new piece of work based on how long similar past work actually took, rather than by breaking the new work into tasks. If your last three API integrations took three to eight weeks, the next one probably will too, adjusted for what’s genuinely different.
Should we stop estimating altogether?
Not for large initiatives; the business needs ranges to plan. For small, evenly sliced work items, though, counting items and using historical throughput is usually as accurate as estimating each one, and much cheaper in meeting time.
How do I give an estimate when requirements are unclear?
Give a wide range and say why it’s wide. Then propose a short, time-boxed discovery or spike on the riskiest unknown. Once that’s answered, re-estimate with a narrower range. Committing to a single date before that is a guess presented as a plan.
Dates slipping and nobody knows the real one?
In a two-week sprint I’ll work with your team to slice the work, build a range you can defend to the board, and ship the first piece.
GMT+2 · Full EU overlap · US East mornings