Definite guide to estimating software projects
Published January 29th, 2021 • ☕☕☕ 13 min read
Why do we try to predict the weather? After all, the forecast doesn't change the weather (not that it wouldn't be convenient from time to time 🌞).
We do it for the same reason as we try to estimate a software project's duration: Because we like to plan. Plans are our best attempt to lay out, predict, and observe the future - in a greater sense, they grant us the illusion of certainty for the future. Nonetheless, plans do help us see, consider, and handle eventualities better and in advance. After all, we make our own future (at least that's my belief), and in our everyday life, this is done easier with a plan.
In our most primitive, daily decision making, we want to know if we should take the umbrella with us to work or go out with friends to enjoy delicious pistachio ice in the hot sun.
As software engineers, product managers, and entrepreneurs, we want to know when a project (or its milestones) will be delivered. This information helps to coordinate with teams and solo contractors as different parties often depend on previous deliverables. It allows us to create roadmaps, price clients, and extrapolate business processes.
In most regions, your weather app and the news usually forecast the weather much more reliable than people like to think, at least for ~5 days. Besides the fact that weather forecasting is still getting better, the applied accuracy and precision make it useful in the first place.
Likewise, it is beneficial to estimate your software deliverables as accurately as possible - and that really holds true for all participants. If the forecast turns out hugely deluded in that the goal is achieved much later, it's usually even worse than no estimate at all. With that, I want to hand you some ideas, rules, and tools to help you perform accurate estimates on your written software.
1. The more you know, the more accurate the estimate
Preparation is half the battle won. That is because it leads up to knowledge, which will allow you to make better estimates. How will you assess the time effort required if I tell you that I "need a new website"? It's impossible! What kind of website? How many pages? Does it need dynamic content? Who should be able to add, edit, and delete content how and where?
Obviously, the more you know about a project or task, the more confidently you can give an accurate and precise estimate. The margin of incorrect and incomplete data increases the error rate of weather forecasts for every subsequent day in the future. There is a lack of essential, reliable data for the future, and the same is true for your estimations.
What describes your task or project is commonly known as a specification. You want it to be as detailed and complete (which is up to the judgement of the person doing the estimation) as only possible. As the person assigned to do both, the work and estimation, strive for a specification with as few unsettled questions as possible. In reality, this will often be an unachievable state.
In these cases, it is okay to trade off the precision and confidence of your estimate, saying something along the lines: "I'm 70% confident that this project will take 40-100 hours of work". Of course, the numbers in this example are just for show. They're meaningless. Still, they can incentivize others to establish a more detailed spec and, most importantly, prevent them from relying too much on those vague milestones or projects. In any case, do not commit to giving accurate and precise estimates if you deem the specification incomplete.
Note that a made estimate doesn't have to be final. It is a good idea to readjust your assessment with every relevant information you receive and push for open questions to be answered during ongoing work.
Also, suppose you are part of a development team and have a lead or product manager. In that scenario, chances are that your PM will be taking over this part and cleanly provide you with assignments in SCRUM fashion (or utilizing a different representation).
2. Split every feature into subtasks
Now that you have a detailed specification written in front of you, you can start dividing all those features into subtasks. Think atomic - the tinier the task, the more accurate you will be able to predict the effort that needs to go into it. Get extremely clear about the requirements of this one checkout form that your client wants.
Will you be validating the user input on both, server- and client-side? Will you do the style pixel-perfect from a PSD file? How much effort is it to make the checkout PCI compliant? Do you need to write tests for it (just kidding - of course, you're writing them as part of your TTD process🥸 🕵️)?
Also, identify meta-tasks, which are not precisely related to the feature but need to be considered. For example, are you familiar with the codebase? If not, you might add a subtask to become acquainted with it.
Optimally, you will end up with not further dividable tasks, each with its own time estimate. Not only will this list of small tasks dramatically increase your confidence in estimating the full feature, but it will serve you as a red thread throughout your work and prevent you from getting lost in anxiety.
3. Stand your ground
In reality, a stakeholder who does not do the work will often try to impose their estimate on you. Similarly, you may be tempted to give a more precise or optimistic estimate - people do this because they want to make a good impression, have too good intentions, or because they don't want to feel like an imposter taking a longer time than they think someone in their position should take.
I can only say one thing here: You can't change the weather. If it's going to be rain, say it. If you don't know because you lack data on wind speed and direction, say it. Don't let others or yourself bully you into giving an unrealistically optimistic estimate.
I'm guessing, if you are one of the people who do give unrealistic estimates in named situations, you probably already knew and will likely not change just because you're reading this article. I suggest you listen deeply inside yourself why you're doing it and try to fix the problem at the root. Talking to a friend or a colleague that you trust can also help.
4. Who writes the code should do the estimate
Your experience, knowledge, preferred tooling, and work routine is unique to you, so there is a good chance everybody will give different estimates for the same feature or project. But if you are the one writing the code, you get to forecast how long you will take.
In a short moment of a well-intended perspective change, if you are the client or product manager, restrain from imposing your estimates on developers - you still cannot change the weather by giving a different forecast.
What you can do in this case, though, is to ask more than one developer for their estimates. If the assignment is big enough to justify both you and the developing parties' overhead, it can help you save time by merely delegating the right tasks to the right folks. Of course, this presumes that the people you're asking for their estimates themselves know how to make an accurate forecast.
I am totally not trying to make you share this article, but you should send it to as many people as possible and share it on Twitter, so everybody can learn how to estimate software projects correctly. Totally not trying to spread this article! 🥸
5. Ask others for technical feedback
While I believe that it's useless to ask others for their time estimate in order to get yours more accurate, it makes perfect sense to have someone else inspect your feature specification with all the subtasks divided (they should be developers, too). I would also remove all your estimates, merely to prevent them from pouring their time-related ideas on top.
Optimally, they will catch a mismatch between the specification and your very technical subtasks. Chances are, you have overlooked a building block. You hit the jackpot if they tell and explain to you that a subtask is superfluous.
6. Reduce feedback loops as much as possible and upfront
Of course, you want feedback. But you want it to be reasonable, constructive, and well-timed. Unfortunately, there is a common situation in the dev world where this is not the case. It usually happens when you deal with less code affine clients or other stakeholders in a product owner's role and quickly turns into a special request show.
The situation is that you agree on a project specification (the problem starts here if it doesn't exist in written form), you start working on it, and mid-term the client asks for a major change, which renders almost your entire work pointless.
Although this usually happens to freelancers and agencies, there is no guarantee it won't happen elsewhere. Should such a situation occur, it can have a tremendous impact on a previously made estimate in a very destructive way. Hence, you want to take the correct precautions and prevent it as much as possible:
I suggest getting projects and tasks done as quickly as only possible. This helps a lot because the more time passes, the more new information the product owner will gather and eventually come up with spec-changing feedback. Optimally, this happens after you've finished the work, or even after gathering user feedback from production environment.
Internally, this can be achieved by aligning projects consecutively instead of parallelly. That way, you won't be working on multiple projects for a prolonged time. Another option is to get more hands on the project.
Externally, it is an excellent idea to sit down with the client ahead of time and carve out a more basic, minimal specification instead of merely accepting whatever is handed to you without questions (note how often it gets back to the specification!). Try to assist in drafting the specification not only technically but also functionally (e.g., how a desired outcome can be achieved with less and less complex code, often by marginally adjusting the requirements). Confirm that the product owner has put a fair amount of thought into the project, so there is less chance for a change of mind.
In cases where a client (unfortunately) is ill-informed, you are bound to talk him out of bad ideas (but make sure you understand where he is coming from before you do - he might have a valid point!). If you conclude that he is hurting himself, try to argue him out in the most sympathetic and detailed way possible. Should the client not be willing to listen, accept the situation and follow his wish. After all, you're doing the work for him. Ensure the client understands what the change requests mean in terms of the timeline and payment, document it, and move on.
Sometimes you will end up throwing away days and weeks of work because of new insights or mission realignment. This can be a good thing, too: The stakeholders understand the concept of sunken costs and want you to abandon the task instead of wasting another week of work just for the sake of finishing. Once again, your due diligence is merely to reduce the damage by ensuring each party understands the implication of the change request mid-work beforehand and document it, so there is no bad blood.
7. Find your individual multiplier
Surely, I'm not the first person to think about estimating software projects. If you've ever remotely touched on this topic, you've probably heard of the ubiquitous default multiplier people like to apply to coding estimates: 2x.
I don't know who came up with it, but it often seems to work out reasonably well. When you think of a number of hours which a feature will require to be delivered, multiply it by two, and you'll get a "good enough" estimate.
Although this has served me surprisingly well in the past, I've decided to lift my estimating game on a whole different level, and I encourage you to do the same. Starting from the industry-standard 2x multiplier, let's carve out your very own multiplier.
What gets tracked gets improved.
Estimating is a skill, and skills can be improved. In terms of tracking, you'll want to do the obvious: Create a spreadsheet. Add the following columns in your preferred order:
- Project: The name of the project or anything that lets you identify the scope otherwise
- Feature (optional): For larger projects, this is another scope identifier to prevent an extensive description in the Task column
- Task: A short, precise description of the task
- Estimated: The number of hours you believe this task will require you to finish
- Confidence (optional): A selection between "Very confident", "Somewhat confident" and "Not confident"
- Measured: The tracked number of hours this task required you
- Accuracy: The result of Estimated / Measured
This spreadsheet is for you only. You can start filling it out by dividing the project into features (hopefully, you just need to copy-paste the specification) and features into subtasks.
After you neatly filled the first three columns, estimate all identified subtasks. Don't make a science out of this: thinking 20 seconds about the task and imagining the code to write should be enough to come up with a number. 2x that number and write it into the cell. If you have no lead at all, look up similar solutions in Google for 5 minutes at most, and then estimate (and again, 2x it). Optionally select your Confidence level for the task to indicate how certain you are of your forecast.
You've finished the estimating part. Now you have a detailed view of what you need to do and a reasonably good idea of how long every feature and the whole project could take (→ sum up the feature- and project-scoped tasks). You are left with tracking your work hours on every task and adding them to the Measured column. Once you do this, the Accuracy column will display a number.
Don't worry about interpreting your accuracy yet: Disregard it entirely until you have amassed a significant amount of tasks to evaluate (I think you are good to go with about ~20 estimated and measured tasks). Your goal is to get accuracy as close as possible to 1. If the number is less than 1, you've overestimated a task. If the number is higher than one, you've underestimated a task.
With 20+ rows of data, it makes sense to play around a little. For example, your average accuracy can provide a tendency to decrease or increase your multiplier at the time (if you just started it, it's 2x). You can also group your tasks by various scopes. For example, maybe you tend to overestimate backend (contextual scope) tasks. Or you habitually underestimate tasks with a high confidence level (that's me, by the way 🤡).
I invite you to try this system out. It's very low effort, but high discipline - a lot like brushing your teeth (I spend less than 10 minutes on any given day in that spreadsheet). On the bright side, using this tool, you will reap immediate results in the form of increased productivity and drastically improve your estimating abilities.
On communicating estimates
Here we are, at the crucial moment of information exchange. We have reached the peak of the mountain, guiding us by eyesight during all the considerations and hard work. What now?
While you may track atomic tasks in hours, this is usually not what you want to communicate to other parties. Depending on whom you are talking to, it makes sense to translate hours into days, weeks, and months.
In these cases, you want to gauge how many productive hours your days have on average and how many days you work per week. If vacancies are coming up, you need to consider them. You may want to add some time buffer for unexpectedly occurring situations both in your private and project scope. When you're planning projects with clients, you'll also want to provide a price estimate along with the time estimate, so have an idea how you convert between those.
In a perfect world, you want to estimate with complete project understanding and optimal awareness of other stakeholders' situation. How would a useful estimate look like for your developer colleagues ("I will implement those few lines of functionality that you depend on until afternoon!"), project managers ("This feature should take me about 3-4 days."), or clients ("We can get you until milestone A in about 6-8 weeks for $20k or if you need to present it to your investors in 3 weeks, we can put your project on high priority for $65-70k.")?
If you ask relevant questions about the project and the stakeholders' position, you will find openings to alter the specification to fit it into the desired estimating parameters ("If you want to pay less than $65k and still show the project to your investors, we should think about slimming down the features to fit it into your budget.").
When it comes to the real world, you will have to stand your ground a lot and continuously trade-off precision (how exact your prediction is) and accuracy (how correct your prediction is either in terms of likelihood or in hindsight) against your confidence-level (how sure are you that your estimate is accurate?) and lacking project-specification. The last step is to put all this into unapologetically simple, uninspiring words and sentences.
Estimating in software development is useful. And even if you happen to disagree on that, there is no denying that, in reality, people will ask for your estimate whether you like it or not.
Frankly, even with all the provided guidelines and tools and advice, you will still get many estimates notably wrong. This probably won't change unless you find a working crystal ball, and that's perfectly fine. I'm not trying to get you to do perfect forecasts - I'm merely suggesting to make them good enough to be useful and prevent disaster.
Want to get done more, faster?
Time estimation is a tool for planning, a virtual construct, so that the ones in managing roles can plug the numbers into some system, coordinate, and provide a roadmap for stakeholders.
Just as you can't change the weather, you can't reduce the time of a task by merely assuming it will take less time. That will accomplish nothing but stressing out yourself (or your team) even more. I like the idea of a healthy amount of pressure on people to increase the output, but unrealistically cutting down the time to deliver for no other reason than having a lower number written in some spreadsheet is not the best idea.
Suppose you want to increase the speed of the development of your software project. In that case, you will have to step outside the box of estimating and look at your very situational fundamentals and identify the bottlenecks.
An article on this topic is in the works, and if you'd like to be notified when it gets published, you should subscribe to my newsletter (form below).