The biggest cost driver is never the technology stack — it is almost always how much is still undecided. Every ambiguity in the specification becomes padding in the estimate. A team that has no visibility into the edge cases must assume the more expensive option. Spending a week on a discovery phase frequently cuts the total much more than any rate negotiation.
Third-party integrations are the next major multiplier. A form that saves data is easy to estimate; the same screen connected to a legacy ERP is a different problem. The unknown lives in the counterparty: poor documentation, waiting on someone else’s team, fields that mean something different on each side. Ask any vendor to break integrations out as separate items, because this is the usual source of overruns.
Non-functional requirements can easily double the estimate. An application used by a handful of staff has almost nothing in common with the same functionality serving public traffic. Audit and compliance requirements, uptime targets, load handling, audit logging and localisation add weeks of work. Put them in the brief or else expect them to arrive later as change requests.
The team you are quoted matters. A rate card reveals very little on its own: software development process one senior developer at twice the price can be less expensive in the end than two inexperienced developers who need supervision and web development company rework. Ask as well which roles are billed: delivery management, QA, infrastructure work and design are legitimate costs, but these should be named rather than hidden inside a blended rate.
The number in the proposal is not what you will actually spend. Plan for hosting, third-party licences, observability and a maintenance allowance each year. A useful planning figure is that any production system consumes a meaningful share of the original budget annually for updates, security patches and small improvements. Treating the launch as the finish line has always been the classic mistake.