The dominant factor is never the technology stack — it remains uncertainty. Each unanswered question in the brief becomes a contingency in the estimate. A supplier that cannot see the exceptions and edge cases must assume a pessimistic case. Putting two weeks into a proper discovery often reduces the overall figure by far more than negotiating the rate.
Third-party integrations remain another reliable source of cost. A form that saves data is easy to estimate; the same functionality wired into an old accounting system is not. The unknown lives in the counterparty: poor documentation, waiting on someone else’s team, inconsistent data. Ask any vendor hire php unit testing developers to price integrations separately, as this is where estimates break.
Non-functional requirements can easily double the budget. An internal tool used by twenty people costs far less than the same idea serving a hundred thousand users. Audit and compliance requirements, high availability, scalability, data retention rules and multi-language support add weeks of work. Put them in the brief or else expect them to arrive later as change requests.
Who actually does the work matters. An hourly rate says little on its own: a senior engineer at a premium rate is often less expensive in the end than two juniors who need supervision and which is better vue or react rework. Check too which roles are billed: delivery management, testing, release engineering and design are legitimate costs, but these should be visible in the estimate.
The number in the proposal is rarely what you will actually spend. Budget for hosting, subscriptions and licences, logging and alerting and a legacy code maintenance services allowance for every year the software runs. A common working assumption is that a live system needs a noticeable fraction of its original build cost every year simply to stay current. Leaving it out of the budget remains the classic mistake.
