Why software projects run over budget — and how they do not
Overruns are rarely a estimation problem; they are an undefined-scope problem. When fixed price works, why a paid discovery phase is cheap, and what belongs in the contract.
A software project going over budget looks like an estimation problem. It is not. Estimation is predicting how long a known piece of work takes. On projects that overrun, the problem is that nobody knew what the work was.
The four real causes
1 · Scope was discussed, not written
“Users should be able to log in” is a sentence, not a scope. Does it include password reset, email verification, two-factor authentication, Google sign-in, session duration, multiple devices, account deletion, role management?
Each is separate work. If all eight sit under the heading “login”, the supplier may have priced three while the client meant eight. The gap surfaces in month three.
The fix: write scope as acceptance criteria, not as a feature list. “When a user forgets their password, they receive a link valid for 15 minutes” is not open to interpretation.
2 · The other side of the integration is unknown
The least predictable item in any project is talking to another system. The accounting software’s API may be undocumented, the courier may have no test environment, the bank’s integration process may take six weeks.
That risk is unknowable at quoting time. Giving a fixed price for something unknowable means either the client or the supplier takes a loss.
The fix: on integration-heavy projects, run a paid discovery first. One week: read the other systems’ documentation, open test accounts, run one end-to-end trial. A realistic number comes out of it. That week looks expensive; the alternative is a six-month dispute.
3 · The decision-maker is not on the project
During development, several small decisions arise each week: is this field required, how is this list paginated, what should this error say?
If the person authorised to answer is reachable once a week in a meeting, the team either waits or guesses. Waiting is delay; guessing is rework. Both cost money.
The fix: name a single decision-maker on the client side and put a 24-hour response commitment in the contract.
4 · “Small” requests accumulate
Thirty requests, none of them more than two days on its own, add up to sixty days. Because each is reasonable, none gets refused — but together they are half the project again.
The fix: keep a simple change log where every out-of-scope request is approved in writing with its time and cost. The goal is not to block requests but to make the total visible.
Fixed price or time and materials?
Both are right — for different work.
| Fixed price | Time & materials | |
|---|---|---|
| Scope clarity | Must be high | Can be uncertain |
| Who holds risk | Supplier | Client |
| Adapting to change | Hard, every change is a negotiation | Easy |
| Typical use | Defined, repeatable work | Product development, discovery |
The hidden cost of fixed price is this: the party carrying the risk prices it in. Ask for a fixed price on uncertain work and the number you pay contains an invisible insurance premium. If scope is genuinely clear that premium is small; if it is not, either you overpay or the supplier takes a loss and quality falls.
The practical route: fixed price for discovery, staged fixed price for delivery. Each stage’s scope becomes clear at the end of the previous one.
What belongs in the contract
- Acceptance criteria. Which sentence, once true, means the work is done.
- Change management. How out-of-scope requests get priced, and who approves.
- Source code ownership. Whose account holds the repository at handover.
- Environment access. Whose name the domain, hosting, database and third-party accounts are in.
- Warranty period. How many days after handover bugs are fixed free, and how a “bug” is distinguished from a “new request”.
- Handover package. Setup documentation, the list of environment variables, an architecture summary.
The last item is the most skipped and the most expensive. A project without handover documentation gets rewritten when the supplier changes.
Honesty in estimates
Be careful with a team that gives you a single number. An honest estimate is a range, and the width of the range measures the uncertainty.
A team that says “6–8 weeks” has thought about it. A team that says “7 weeks” either knows the work extremely well or is saying it to close the sale. One question tells you which: what is the riskiest assumption in this estimate?
If they can answer, the estimate is real.