How to scope a fixed-fee SOW that doesn't lose money
The margin on a fixed-fee project is decided before anyone writes code.
A fixed-fee statement of work protects margin through four mechanisms: an estimate built from decomposed work rather than a buffered guess, a written assumptions list, an explicit exclusions list, and acceptance criteria that make "done" testable. Projects that lose money almost always failed at one of those four in the document, not during delivery.
Why fixed-fee projects lose money
Overruns are usually attributed to delivery: the team was slow, the client was difficult, the requirements changed. Trace them and the cause is almost always earlier: the estimate never included the work, or the document never excluded it.
This is good news. Delivery discipline is hard to change and slow to improve. A scope document is a two-week habit change with immediate financial effect.
It is also worth being precise about what a fixed fee is. It is a transfer of scope risk from the client to you, priced. If the document does not bound what you are absorbing, you have not priced the risk, you have simply accepted all of it. Everything below is about drawing that boundary in a way a client will sign.
Estimate from decomposition, not from a feeling
The failure pattern is adding up the parts of the work the team can picture and applying a buffer. Buffers hide the fact that nobody knows how long the unpicturable parts take, and they get negotiated away first because they look like padding.
Decompose until each line resembles something the team has actually done, then estimate those lines against measured velocity. Where a line has no precedent, do not buffer it: carve it out as a separate discovery phase with its own small fixed fee. A client will accept "we'll spend two days establishing this, then price it" far more readily than a large number with no visible basis.
How far down to break it
There is a rule of thumb for how far down to go. Decompose until no single line exceeds roughly one person-week. Anything larger is a container rather than a task, and the overrun will hide inside it where nobody can find it afterwards. That is not a stylistic preference: if a project goes over and the smallest unit of measurement is a fortnight, you cannot say where, so you learn nothing and price the next one the same way.
Comparison beats duration
Atlassian's estimation guidance makes the same point from the other direction: relative sizing works because humans compare well and forecast duration badly. A decomposed list converts a duration question, which people answer poorly, into a series of comparison questions, which they answer far better.
Write the assumptions down
Every estimate rests on things that must be true: content is supplied by a date, one round of feedback consolidated from all stakeholders, staging access provided in the first week, third-party API documentation accurate. These are known at scoping time and forgotten by week four.
An assumptions list does two things. It makes the estimate conditional in writing, so a broken assumption is a re-estimate rather than an argument. And it surfaces the risks during the sales conversation, when the client is still receptive.
Write each assumption so a broken one is observable rather than arguable. "Client provides timely feedback" is not an assumption, it is a hope. "Consolidated written feedback within five business days of each delivery" is, because on day six you can point at the document instead of at the client.
The assumption that breaks most often is the third-party one. An API that does not behave as documented, a payment provider whose sandbox differs from production, a client's existing system with no test environment. Name every external dependency explicitly and state what happens to the schedule and the fee if it does not behave as documented. That single paragraph has better economics than any other in the document.
Exclusions are the highest-value section
Exclusions are the things a reasonable client would otherwise assume are included. Data migration from the legacy system. Training. Content entry. Post-launch support beyond the warranty window. SEO redirects. Accessibility remediation. Browser support below a stated version.
Naming them feels adversarial. It is the opposite: an exclusion found in week one is a conversation, and the same exclusion found in week nine is a dispute. Clients who read a thorough exclusions list generally conclude the provider has done this before.
Accessibility needs its own line
Accessibility deserves its own line because it is the exclusion most often waved through and the most expensive to retrofit. Do not exclude it vaguely and do not include it vaguely. Either name the conformance target and the pages it applies to, or exclude remediation and say so. The W3C publishes the WCAG 2.2 success criteria at three conformance levels, so "Level AA on the templates listed in section 3" is a scope line someone can price and test. "Accessible" is a scope line someone can argue about for a month.
Put the number in the document
The same logic applies to browser and device support, data volumes, and the number of languages. Anything with a number attached should carry the number in the document. Anything without one is being priced on the client's imagination rather than yours.
Make acceptance testable
"Client approves the design" is not acceptance criteria. "The client's named approver signs off in writing within five business days of delivery; feedback is consolidated into one round" is. The distinction decides whether a milestone can be invoiced.
Write acceptance per deliverable, in terms someone can test without a judgment call. Tie payment milestones to accepted deliverables rather than calendar dates: a date-based milestone can be reached with nothing accepted, which is how projects run three months past invoice.
Per item and across everything
Two levels are needed and they are frequently conflated. Acceptance criteria are per item and answer whether this particular thing does what it was supposed to. The definition of done applies to everything and covers the standing bar: tested, reviewed, deployed to staging, documented. Without the second, every deliverable arrives with a different idea of finished attached to it.
Deemed acceptance after the window
Add a deemed-acceptance clause and use it. If written feedback does not arrive within the stated window, the deliverable is accepted and the milestone is invoiceable. Without it, a client can stall a project indefinitely at no cost to themselves while your team holds capacity open.
Fixed fee, banded hours, or time and materials?
| Model | Use when | Risk sits with | Requires |
|---|---|---|---|
| Fixed fee | Scope is genuinely knowable | Provider | Decomposed estimate, tight exclusions |
| Banded hours | Shape is clear, depth isn't | Shared | Band assumptions in writing |
| T&M with cap | Discovery is the work | Client | Trust, and weekly burn reporting |
The common and expensive mistake is quoting fixed fee on work that belongs in a band, because the client asked for a number and nobody wanted to explain a range.
There is a test for which row you are in. Ask whether you could write acceptance criteria for every deliverable today. If yes, the scope is knowable and fixed fee is honest. If you would have to investigate first, you are in row two or row three, and quoting row one means you are selling the investigation at zero and absorbing whatever it finds.
Change control that actually gets used
Most agencies have a change control clause and have never issued a change order. The clause is not the problem; the moment of use is. Scope changes arrive verbally on calls, in the middle of a friendly conversation, and re-pricing feels petty.
Make it small and routine. A change record is three lines (what changed, the effort delta, the decision) sent the same day, with the option to absorb, defer, or re-price. Used routinely it stops reading as escalation and starts reading as competence.
The second-order effect is the real argument for it. A client who has never received a change record has been trained, by you, that scope is free. By month four they are not being unreasonable when they ask for more, they are behaving exactly as your process taught them to. The first change record is awkward precisely because it is late.
Absorbing something small is fine and often good business. Absorbing it silently is not, because an absorbed change that is never recorded is a discount the client never knew they received. Record it, price it, then mark it as absorbed. The goodwill only exists if it is visible.
Where this shows up on real programs
The pattern generalises past web projects. A clinical research organization moving to version-controlled database change management had a development team that understood the target state and could not express it as something a VP sponsor could fund. Decomposing it into 159 tracked work items with acceptance criteria, sequenced with dependencies explicit, is what made the program fundable. The decomposition was the estimate, not a step before it.
Platform migrations are the sharper version of the same lesson, because the unknown is quantity rather than difficulty. Nobody knows how many assets are in scope until someone counts them, which is why a migration estimate produced before the inventory exists is fiction and why the inventory is worth buying as its own small fixed-fee phase.
If you are writing these documents regularly and the same three things keep going wrong, the fix is a template rather than more care. That is what statement of work scoping produces: a reusable structure with the assumptions, exclusions and acceptance patterns already in it, so the next document starts at eighty percent rather than at a blank page.
What to confirm before the SOW is signed
Before a fixed-fee SOW is signed: the estimate decomposes to lines the team recognizes, none longer than about a person-week; unknowns are carved into a discovery phase rather than buffered; assumptions are written so a broken one is observable; every external dependency is named; exclusions carry numbers rather than adjectives; acceptance is testable per deliverable and backed by a deemed-acceptance window; payment is tied to acceptance rather than dates; change control has a stated rate and a three-line process; and one person who will actually deliver the work has read the whole document.
The last item catches more money than the rest combined. A scope document nobody on the delivery team has read is a sales artifact, and it will be discovered as one in week three.