The biggest cost driver is never technology — it is almost always how much is still undecided. Every open question in the specification becomes a contingency inside the number you receive. A team that cannot see the exceptions and edge cases will assume a pessimistic case. Spending a week on a proper discovery can cut the overall figure much more than any rate negotiation.
Third-party integrations tend to be the next major multiplier. A feature that touches only your own data is low risk; the same functionality wired into an old accounting system is a different problem. The effort lives in the third party: undocumented APIs, slow approval cycles, data that does not match your model. Ask any vendor to list every external system, because this is where estimates break.
The requirements nobody writes down silently change the budget. A tool used by a handful of staff is a very different build from the same idea handling thousands of external customers. Security reviews, enterprise php high availability, load handling, data retention rules and localisation each add real engineering time. Put them in the brief or else expect them priced as extras.
The mix of people behind the number matters. A day rate reveals almost nothing on its own: a senior engineer at a higher rate can be cheaper per delivered feature than two juniors who need supervision and laravel vs fastify rework. Also ask who else is billed: node js consulting services project management, testing, release engineering and design are legitimate costs, but these should be named rather than hidden inside a blended rate.
The number in the proposal is rarely the full cost of ownership. Expect cloud costs, third-party licences, logging and alerting difference between flutter and react native a change budget for every year the software runs. A useful planning figure says that any production system requires a meaningful share of the original budget annually in fixes, updates and small changes. Leaving it out of the budget is the classic mistake.