Estimating the effort, duration, and cost of a custom software development project is an exercise in mere guessing. People often ask: “Why can’t you tell me how long it will take to build this application when you have built thousands of software projects over the past 25 years?”
The answer is simple: for the same reasons you can’t accurately predict how long it will take to go from point A to point B — despite having driven a car for decades and having access to Google Maps.
We may have a list of desired functionalities — and even customer journeys and user stories — but those do not provide all the details needed to build software. I have yet to see a client provide a comprehensive description of all the functionalities, design views, permissions, workflow logic, copy, user acceptance tests, etc., that will need to be implemented. It’s just too hard to think through every possible scenario upfront. For this reason, we ask questions (lots of questions), but there are always details we miss.
This is equivalent to estimating how long it will take (and how much it will cost) to drive from San Francisco to Chicago, while stopping by Death Valley and the Grand Canyon along the way. This is a great start, but it’s missing many details, such as the date and time of departure, how many people are in the car, how much stuff you’re hauling, how many hours you want to drive per day, what vehicle you’re driving, and more.
Clients always think they know what they want, and sometimes they do provide a very long list of requirements (RFP, anybody?). However, what’s in one person’s head is notoriously difficult to accurately describe on paper. Translating a human decision-making process into computer logic can also be tricky — those are the infamous “edge cases.” Clarification is always necessary, leading to specification changes.
Returning to the trip analogy, you may send a very detailed itinerary but fail to mention that you actually intend to go on a “Death Valley Day Tour with Sunset and Stargazing” (starts at 9am, back by 11pm) — but only if the weather is nice.
Even if we spent hundreds of hours carefully documenting what the system should do and what the UI should look like — view by view, modal by modal (hello, waterfall!) — we would still have to make adjustments. Priorities inevitably change over the course of months of development.
Clients get excited by early demos and ask for new features (“tweaks”). Early users provide unexpected feedback. Suddenly the need for tradeoffs rears its ugly head. Not to mention, we still need to document non-functional specifications and processes that must happen behind the scenes. As a result, initial requirements always evolve during development as the mythical rubber meets the road.
Going back to our trip scenario, the family decides against the Day Tour and opts for a helicopter ride instead. Aunt Emma insists on seeing the sunrise at the Grand Canyon, and Dad realizes he needs a better audio cable to play music in the car. All of these last-minute changes impact the timeline.
At the start of a project, we usually know what language we’ll code in (Python), what backend we are going to use (e.g., Django), what front-end we will choose (e.g., Next.js) what database we’ll rely on (e.g., Postgres), and so on.
However, as the project progresses, we may realize we need Celery for queueing processes, or that a new package we read about on TLDR could make things easier — it does, but not without some head-scratching first. We also have to adapt to changes in third-party services and adjust when a cloud provider stops supporting key features. After building in increments for a while, re-architecting some sections may be necessary to integrate different pieces or solve newly discovered problems.
Software development is a creative and R&D-driven process. The second time we build something, it goes faster — but with custom software, we never get that second time.
Bringing this back to our family trip, the car gets a flat tire in Needles, CA (true story!), and unexpected weather conditions require tire chains, further delaying the journey.
The exact same circumstances have never happened before and will never happen again. Even if someone from the future came back and handed us the final specifications, we still couldn’t foresee all the potholes: a key stakeholder leaving the project halfway through, a dependency becoming unavailable, a developer misinterpreting requirements, a third-party tool becoming unreliable, a security vulnerability creeping into the framework, or better technology being released (AI, anybody?), etc.
Back on the road, Dad takes the wrong exit, the family is forced onto a detour due to a collapsed bridge, and Grandma gets her credit card stolen. Who could have known?
There is no such thing as a Lego-like, step-by-step instruction manual for custom software projects. By definition, what’s being developed — with a specific set of requirements — has never been done before, making it impossible to accurately and reliably predict the time, effort, and budget required.
So, does this mean we are asking for a blank check at the start of each custom software project? Of course not.
Drawing from our 25+ years of experience, we have developed a home-grown “Map View” tool designed to help us provide better estimates. Map View considers all the usual elements of a custom software project while also incorporating project-specific details. Still, all stakeholders must understand the result is just that — an estimate. A best guess. The reality is that we will know exactly how long it takes and how much it costs only once we get there.
Staying open to changes and ensuring continuous feedback are key to a successful delivery.
Want to bring your game-changing idea to life? Let’s talk.