I quote fixed price. Client describes what they want, I count what's in it, I give one number. That number has been roughly right more often than not.
It still cost me an entire project's pay.
Count roles, not features
The obvious way to price a build is to list features and put a number on each. That works, but feature count is a weak proxy for the actual work. The better signal is how many roles the system has.
One kind of user means one set of screens, one permission path, one thing to test. Add an admin and you've roughly doubled it. Add a tenant, or a teacher alongside a student, and it compounds again.
Three roles isn't three times one role. It's closer to the number of pairs you have to reason about — who sees whose data, who can act on whose records, what happens when two roles touch the same object.
So "an LMS" tells me almost nothing. "An LMS with students, teachers, and a school admin" tells me most of what I need.
Who the users are matters too, for a non-technical reason. Students tolerate rough edges. A corporate client has procurement, a brand, and someone paid to have opinions about spacing. Same feature list, more work to reach "approved".
A floor, not a buffer
Most people pad a percentage — feels like six weeks, quote eight. I use a floor: nothing goes out under two months.
Small projects are where estimates break, not big ones. A big build gets scoped carefully because the number is scary. A small one gets waved through on instinct, and then discovery, revisions, deployment and handover turn three weeks into seven.
Where it went wrong
A project I'd quoted, mid-build. The client started adding features — not once, steadily, the way you do when nobody's told you it costs anything.
I built some of it. When it kept coming, I said the additions were outside what we agreed and asked to price them.
She didn't want to pay more. So she pulled the project and paid nothing.
For a long time I read that as an estimating failure. It wasn't.
My number for the original scope was fine — she never disputed it. What failed was that nothing connected new work to new money. Scope arrived free until I objected, and by then objecting looked like changing the deal.
The payment structure was the other half. Ten percent upfront, nothing staged after. She walked with the build nearly done and me paid for almost none of it. Cheap for her to leave. Expensive for me.
A client who walks at week five should already have paid for weeks one to four.
What changed
Scope goes in writing before anything gets built — what we're making, and specifically what done looks like.
Not to be adversarial. So that "can we also add…" has an obvious answer: yes, here's the cost, here's what it does to the timeline. A written scope isn't there to say no. It's there so yes has a price attached.
My take
Estimation is the skill everyone talks about and the wrong one to obsess over. You'll get better slowly and never be exact.
Terms you can fix immediately. They're what decides whether being wrong costs you a week or costs you everything.