Software Estimates and Other Lies
I’m walking fast. Sector 4, alley 33, location 5, part 3. I scan another dusty box and drop it in a gray basket, completing yet another order. The bell rings lunch break. “Don’t work so fast”, my colleague complains, “it’s useless!”. But my bosses are happy: I have a very good “pick rate” and it’s all they care about. They know how many orders we can process in a day and as long as that number is high, the business is running smoothly. As for me, I’m getting my first paychecks and regular cardio before starting engineering school. It’s a win-win situation.
Fast-forward a few years later. “How long is this going to take?”, I’m asked. Here, there is no Pick Rate, no bell, no conveyor belt. We are building an application and the stakeholders need to know how long it will take and how much it will cost. The thing is, no one has a clue. “I don’t know”, I reply. “Somewhere between an afternoon and two weeks?”. I’m asked for a more specific figure, which I make up on the spot, insisting that it’s probably very wrong. I will go on to work on a variety of software projects over the next decade, seldom meeting anyone who can provide realistic software estimates.
Why is that? Warehouses know how many orders they can process in a day. The whole construction industry relies on estimates and, although they’re not perfect, they are at least correlated to reality! Mechanics know how much time it takes to inspect a car or change the brakes. Why is software so different?
The mechanic changing brakes is more or less replicating a procedure he has done over and over. There might be some variability due to circumstances but the time required will always be within a certain range. The same applies to laying a brick wall or fulfilling orders in a warehouse: it’s a form of replication.
But software replicates itself.
Whenever you install an application on your phone, it gets replicated. Whenever a developer uses an existing library, it’s replication again. Developing a new application is analogous to designing a new kind of car, building or industrial process: there is a lot of uncertainty, as if it already existed, we would just copy it!
Generally speaking, if a developer codes the exact same thing over and over again, there is something wrong with their approach.
So here is my magical formula for estimating how much time and money a whole software project will require: don’t. Every new application represents work that has never been done before so no historical data can be used as a basis for an estimate. Without supporting evidence, estimates are an illusion of certainty at best.
But then, what can one do to make business decisions in such an uncertain world?
Dividing a project into a lot of tiny subtasks has several advantages. One of them is that it brings clarity. As Daniel Kanheman famously put it in Thinking, fast and slow, “what you see is all there is”. When we don’t see something, it’s as if it didn’t exist. The more you subdivide work, the less likely you are to overlook important details.
Another advantage is that patterns will emerge. Even if the whole project is very innovative, a lot of the small tasks comprising it are likely to look a lot like tasks that have been done before.
By consistently measuring how much time common, smaller tasks take, partial estimates become possible. Even if you can’t tell how long the team will take to implement an important new feature, maybe Mary knows how much time she usually needs to add a new table to the database, update the application’s data model accordingly and add appropriate unit tests. That’s valuable information. Note that this is not transferable: maybe Josh would need more time since he isn’t as familiar with that part of the code base, or for a variety of other, entirely valid, reasons. That’s OK.
Instead of trying to estimate a whole project at the beginning, when there is barely any basis for estimating anything, start with the smallest feature set possible to get a minimalist app ready as soon as possible. Then, work incrementally from there, applying the learnings and experience of one iteration to the next.
Developing a piece of software will never be a predictable, repeatable process. However, by subdividing the project into smaller tasks, measuring how much time they take and iterating, you can get more clarity along way. You’re not fulfilling orders in a warehouse. You are designing a new kind of warehouse.