When we moved to fixed price against a written scope, the objection came quickly. It often came from our own engineers. You cannot estimate work you have never built. Any number you commit to is a guess, and a guess with a penalty attached can become a slow way to lose money.
That objection is half right, and the right half matters. If we refused to estimate, the other route would be charging by the hour and transferring the entire risk to the client. We decided we were not willing to do that.
What follows is what we actually do. It is the method we use to make fixed price work when the work is new, uncertain, or only partly familiar.
Some unknowns can be estimated, and some have to be investigated first
Almost every estimate that goes badly wrong has the same root cause. Two different kinds of unknown get bundled together and treated the same way.
The first kind is work we have done before in a different shape. These are familiar building blocks, even when the exact project is new.
- Building an authentication flow.
- Building an integration with a documented API.
- Building a reporting screen.
- Building a payment path.
We have done these dozens of times. The variance is real, but bounded. Historical data tells us what the spread looks like.
The second kind is work where the difficulty is actually unknown. This is where experience helps us ask better questions, but experience alone cannot give a responsible number.
- Integrating with an undocumented legacy system.
- Achieving an accuracy target with a model on a data set nobody has evaluated.
- Meeting a performance requirement on a codebase we have not profiled.
For this second kind, the honest range is not plus or minus thirty percent. It is a factor of five. No amount of experience narrows that range, because the uncertainty is about the world rather than about us.
Estimating the second kind as though it were the first is how a fixed price engagement becomes a loss. Refusing to distinguish them is how a proposal becomes uselessly padded.
Price the discovery before you price the main work
For the second kind of unknown, we do not estimate the main scope straight away. We propose a short, separately priced piece of work whose only purpose is to remove the uncertainty. We also say plainly that we cannot responsibly quote the main scope until that work is done.
That investigation might be three days connecting to the legacy system and reading its actual behaviour instead of relying on its documentation. It might be a week building an evaluation set and measuring what a model achieves on a sample, before anyone commits to an accuracy number. It might be two days profiling a codebase to learn whether the performance target is a tuning exercise or a rewrite.
Clients occasionally read this as a way of billing twice. The framing that works is comparative. We can give you a number now with a large contingency in it, and you will pay for that contingency whether or not it is needed. Or you can spend a small amount finding out and get a real number.
Almost everybody takes the second route. The ones who do not usually have a procurement constraint rather than a preference.
Use past projects instead of task totals
Task level estimation feels comforting. You list everything, add up the days, and get a total. It is also systematically wrong.
The list is always incomplete. The missing items are correlated with difficulty. Nobody forgets to list the login screen. Everybody forgets the third party that turns out to rate limit.
We estimate by reference instead. This project is shaped like that one. That one took eleven weeks. This is somewhat larger in the integration dimension and somewhat smaller in the interface dimension. Twelve to fourteen weeks.
This only works if you keep records, which is the part most firms skip. We keep the estimate and the actual for every engagement. We also keep the difference and a note on why. That archive is the single most valuable estimating asset we have, and it took three years to become useful.
The contract number includes risk
Internally, we hold two numbers. The target is the honest expectation. The commitment is what goes in the contract, with contingency added.
The size of the contingency depends on the ratio between the two kinds of unknown. It ranges from about fifteen percent on well understood work to considerably more.
We do not pad silently and then treat the padding as margin when it is unused. When contingency is unused, it shows up as us finishing early. Finishing early on a fixed price is the mechanism by which the model works for us.
The incentive is exactly right. We make money by being fast and accurate rather than by being slow.
Write the scope before pricing it
You cannot fix a price against something vague. The discipline this imposes is the main reason our estimates improved.
We write a definition of done, meaning the agreed description of what finished work must include, and both parties sign it. That forces ambiguity to surface at the point where it is cheap.
The conversations this produces are frequently difficult and always useful. The questions are simple, but they matter.
- Does the reporting screen need to export?
- Which browsers?
- What happens to existing data?
- Is the integration one way or two?
- Who provides the test environment for the third party?
- What happens if it is not available in week three?
Every one of those, unasked, is a change request later. Asked now, it is a sentence.
Make assumptions visible and binding
Every fixed price we quote carries a short list of assumptions. They are not boilerplate. They are the conditions the estimate depends on.
- The third party’s sandbox will be available from week two.
- Design will be signed off by a named date.
- The client’s data export will match the sample provided.
- Access to a subject matter expert for two hours a week.
If an assumption fails, that becomes a defined event with a defined consequence, agreed in advance. It avoids a negotiation held under pressure in week six, which is what happens when the assumption was implicit.
This part protects the client more than us. It makes visible the things they need to do, early enough to do them.
Break the work down until the pieces are familiar
A useful test is whether a piece of work can be estimated to within about twenty percent. If it cannot, it has either not been broken down enough, or it belongs in the uncertainty buying category.
There is no third option where a large vague thing gets a confident number.
We keep decomposing the work until each piece is recognisably like something we have done, or is explicitly flagged as needing investigation. The pieces are usually between two and ten days. Smaller than that and the overhead of tracking exceeds the value. Larger and the variance hides.
Our estimates have been wrong four times
It would be dishonest to describe a method without describing its failures. In three years of fixed price work we have materially overrun four times.
The causes were specific.
- Two were the same cause: a third party system behaved differently from its documentation, in a way our investigation phase did not surface because we tested the documented paths rather than the awkward ones.
- One was a data quality problem. The sample export we were given was clean. The full data set had eleven years of history including three schema changes and a period where a required field was optional.
- One was our own optimism on a performance target, where we believed a tuning approach would be sufficient and it required an architectural change.
We changed the investigation checklist after the second one. Specifically, we now test error cases and rate limits during investigation rather than assuming them.
After the data quality problem, we now ask for a full export or a genuinely random sample, never a curated one.
On the performance target, we absorbed it, which is what fixed price means. It cost us about six weeks of a team’s time.
Four in three years is a rate we can carry. The important thing is that the client did not carry them, which is the entire proposition.
Change is easier when scope and understanding stay separate
The standard criticism of fixed price is that it makes a project rigid, and that any change becomes an argument. That is a fair description of how it usually works. It is a consequence of pricing badly rather than of pricing fixed.
We separate two things that usually get conflated. A change in understanding is different from a change in scope.
If we both believed the export was a comma separated file and it turns out to be a fixed width format, the scope has stayed the same. Our shared understanding has caught up with reality. That is our risk to carry because assessing it was our job.
If the client decides they also want a second export format, that is new scope. It gets priced as a small piece of work with its own number.
Drawing that line clearly in the first week removes almost all of the friction. Clients are entirely reasonable about paying for things they asked for later. What makes people angry is being charged for something they believed was included. The definition of done exists to make that a matter of record rather than of recollection.
Keep the estimate as a range until it becomes a commitment
Internally, we express early estimates as a range with a confidence attached. We resist enormous pressure to collapse that range too early.
Somebody always wants a single number for a board paper. Giving one before the uncertainty has been bought down converts an honest range into a false commitment that will be quoted back for the rest of the project.
The phrasing that works is to give the range and the date on which it becomes a number. Twelve to eighteen weeks now, a committed figure within nine days of starting the investigation phase.
That is a concrete promise about when they will have certainty. That is usually what the person actually needs, and it is far better than a number invented to end a conversation.
Model work has to be measured before it can be priced
Work involving a model deserves its own note, because it sits almost entirely in the second category of unknown. People persistently estimate it as though it were the first.
The build is often the easy part. Reaching a quality bar is the work, and nobody can tell you how long that takes before measuring where you start.
So we never quote an accuracy target we have not measured. The investigation phase for this kind of work is always the same shape.
- Assemble a held-out set from examples a person has already done correctly.
- Run a baseline.
- Report the number.
A held-out set is a group of examples kept aside for checking the model. A baseline is the first measured result you compare later work against.
Sometimes the baseline is already good enough and the remaining work is small. Sometimes it is far off and the honest recommendation is that this is not currently solvable at the price under discussion. That conversation belongs in week one rather than month four.
We have given that second answer three times and declined the work. Each time the client was better off, and twice they came back with a narrower problem that was solvable.
What we would tell a firm considering this
For a firm considering this model, the advice is simple.
- Start keeping estimate versus actual now, even if you have no intention of changing your model. It is the prerequisite for everything else.
- Separate the two kinds of unknown explicitly in every proposal, and price them differently.
- Never quote a number for work whose difficulty you have not established. Sell the establishing instead.
- Write the definition of done before the price, always.
- Publish your assumptions and make failure of an assumption a defined event.
- Expect to be wrong sometimes, and size the business so that being wrong is survivable rather than existential.
Why we carry the risk
Estimating novel work remains hard, and the method above does not make it easy. It separates the part that can be estimated from the part that cannot. It prices the second one as a small piece of discovery rather than as a large piece of contingency. It also puts the remaining risk on the party better able to carry it, which is us.
That last clause is the whole argument. A client buying software once every few years cannot price the risk of it going badly. A firm that has delivered a hundred projects can. Charging by the hour puts the risk on the party with less information, and the fact that it is the industry norm does not make it defensible.
More on the commercial model in engagement models, and on the method in how we work.








