How much does custom software cost, and what is in a quote?
$800 is the floor for a small, well-defined feature. Everything above it comes from a scoping call, in writing. What that quote contains, and what it omits.
$800 is the floor for a small, well-defined feature. Everything above that comes from a scoping call, in writing, before any work starts.
You are probably holding more than one number.
The number for your work comes from scope, integrations and timeline. A brief carries none of the three.
My name is Ahsan Mahmood. Since March 2026 I have been independent, working on my own products full time and taking client projects alongside them.
This post is about the document that arrives after the call, and about the parts of an engagement people usually find out about later โ the parts that decide whether two quotes were ever comparable.
Why do two quotes for the same project differ so much?
Because they are answers to different questions. Each one encodes a different guess at scope, a different list of what is included and a different idea of what happens once the work is delivered. The numbers look comparable because they are both numbers.
They are not describing the same work. One prices a build. One prices a build and a launch. One prices a build, a launch and the months after it, without saying anywhere that it does.
The clauses that decide the difference are rarely the ones in bold. They are the exclusions, the terms for what happens after delivery and the line about who owns the code.
A quote that answers none of those is not cheaper than one that answers all of them. It is shorter.
What can be quoted before a scoping call?
Floors, never a quote. $800 is the entry floor for work nobody has scoped: one small, well-defined feature, integration or fix on a codebase that already exists, with thirty days of bug fixes after delivery. It describes a shape of work rather than a project.
The services page carries the same floor beside the work it applies to, and pricing carries a floor for each defined package. I do not restate either here.
A fixed number attached to an unscoped brief is a number one of us is going to be unhappy about. The call is free. It is where I say whether I am the right person for the work.
What goes wrong when the number comes before the scope?
Either the number goes up later, or the part nobody wrote down never gets built. Both are worse than the conversation they replaced. The revision is the outcome you were told would not happen. The omission is the one neither of us sees until month two, when a real person needs the thing the brief never named.
Watch how it happens. A brief says the product needs user accounts. Everyone reads that sentence and pictures something slightly different: a sign-in form, or a sign-in form plus password reset, email verification, an administrator who can suspend somebody and a record of who did what.
Nobody is careless. The sentence holds more than one feature and reads like one, which is how briefs work rather than a failure of anybody's attention.
The number is agreed against the shortest reading of it. In month two the rest of the reading arrives, because a real person needs to reset a password and a real operator needs to suspend an account.
Now the two of us are in a conversation neither of us wanted. The number is agreed and the work is underway, so the difference has to come from somewhere.
There is a blunter version of the same problem. Say the agreement is a todo app. A week in, the request is to add e-commerce features to it, on the original date and for the original price. That is not going to happen.
Requirements change, so the cost changes and the timeline changes with them. I say which of the two moved and why, in plain terms, rather than absorbing the change and letting the work come out smaller. A change is re-scoped and re-quoted before it is built.
I would rather tell you on that call that I am the wrong person for the work than discover it together in month two.
What is actually in a written quote?
Scope comes first, and the number follows from it. The document names what is being built, what it integrates with and what the timeline is, which are the three things the number comes from. It arrives in writing after the scoping call. Never from a brief alone.
The exclusions are the part a brief never carries โ and the part that decides the number. An exclusion can read like this: the delivered code transfers on final payment, and the deployment it runs on and the accounts behind it are not included unless this scope names them.
That line is written before work starts, so a change to it later is a conversation rather than an argument.
Four shapes are available: fixed price, milestone, retainer or fractional. The work decides which one fits. Milestone work is delivered against a working demo every week, not a status report. A retainer is a set number of days a month for ongoing work, and it is also what maintenance after delivery is bought as.
Underneath all four the engagement is the same. A scoping call that costs nothing and runs thirty minutes. Scope in writing before anything is built. Thirty days of bug fixes at no charge after delivery.
Who owns the code when the work ends?
You do. Full IP transfer of the delivered code on final payment, with a handover that names where it is deployed and what it depends on. Anything beyond the code, such as the deployment itself or the accounts it runs on, is whatever the two of us agreed in the scope.
That last part is an example rather than a published term: what transfers beyond the code is per engagement, written into the scope before work starts. Who pays the vendors is published and is separate. Hosting, third-party services and store fees are yours, paid to those vendors directly.
The handover assumes I am not available. Documentation that matches the code, and a codebase typed end to end and structured so a second developer can find things.
You are not buying a codebase only I can read. If the project only runs while I am on it, I have not finished.
What does the $800 floor not cover?
A product. The floor describes one small, well-defined feature on a codebase that already exists, with thirty days of bug fixes after delivery โ and a product is a different question that a call answers rather than a page. It is not a starting bid, and it is not an estimate of your build.
After thirty days nothing is automatic. Maintenance, new features and on-call are a retainer you opt into. You can end it. I would rather you leave because you no longer need me than stay because cancelling was awkward.
Three things stay with you in every shape above. The decisions, which a weekly demo can surface and cannot make. The accounts and the access the product runs on, unless the scope says otherwise.
The maintenance after day thirty. That one you buy or you do not.
Tell me through the contact form what you are building and roughly when you need it. The first call runs thirty minutes and costs nothing. The number that follows it arrives in writing before any work starts. If the question underneath yours is how to charge for the product once it exists, pricing and plans without a payment processor is the next one to read.
No page can quote your build. That is what the call is for.
What does a written quote actually contain?
Scope first, then the number that follows from it. The document names what is being built, what it integrates with and what the timeline is, which are the three things the number comes from. It arrives in writing after the scoping call, not before it. What a scope excludes is written into that document before work starts, not published as a standing term.
What happens if the scope changes halfway through the build?
It is re-scoped and re-quoted in writing, the same way the first scope was. A change that arrives in month two is a change to the work. It is not a favour either of us owes the other, and there is a document from the start that both of us can point at while deciding what to do about it. The alternative is the one I will not take: absorbing it quietly and delivering something smaller than what was agreed.
What does the $800 floor not include?
Anything that is not one small, well-defined feature on a codebase that already exists. The floor covers that shape of work with thirty days of bug fixes after delivery. A product is a different question, and a call answers it. The floor is not a starting bid, and it is not an estimate of your build. The defined packages carry their own floors on the pricing page.
Who owns the code when the engagement ends?
You own the delivered code, with full IP transfer on final payment. The handover names where it is deployed and what it depends on, and the code is typed end to end and structured so a second developer can find things. Anything beyond the code, such as the deployment itself or the accounts it runs on, is whatever the two of us agreed in the scope, which is a per-engagement question rather than a standing term. Who pays the vendors is published and is separate: hosting, third-party services and store fees are yours, paid to those vendors directly.
Which shape should the work take: fixed price, milestone, retainer or fractional?
Whichever fits the shape of the work, which is a scope question, not a preference. All four are available and the scoping call is where the right one gets chosen. A retainer is a set number of days a month for ongoing work, and it is also what maintenance after delivery is bought as; it is cancellable and does not auto-renew.
Can anything be quoted before a scoping call?
No: a floor can be published, and a quote cannot. $800 is the entry floor for a small, well-defined feature on a codebase that already exists, and the pricing page carries a floor for each defined package. A floor is where a number starts rather than where it lands, so the number for your work still comes from scope, integrations and timeline.
https://aoneahsan.com/blog/how-much-custom-software-costs-and-what-a-quote-includes