Software estimation is one of those tasks that can feel like a distraction from the “real” work of engineering. In practice, though, I’ve found that making reasonable estimates for engineering tasks is a really useful - if mysterious - skill. So let’s talk about it!
I work on a team of ~8 engineers at a large company. Many other teams depend on our work, and we depend on many others. There is always more work to be done than we have time for, so prioritization and communication are crucial. Software estimates are one of the tools we use to help with project planning.
If I worked at a startup with a single engineering team, like my last job, my estimation process would be really different! But in the kind of environment that I work in today, I find software estimation useful for….
- Sequencing work: What can be parallelized? What work depends on other projects? Do your timelines make sense?
- Staffing: again, what work can be parallelized? If it’s mostly linear, it doesn’t make sense to assign multiple engineers; conversely, parallelizable work benefits from having multiple engineers implementing it.
- Forcing prioritization: there’s only so much time in a day (or week, or month), and a limited number of people per team. Having estimates helps you make explicit tradeoffs and identify the highest-impact work.
- Outward communication: if another team really wants or needs something that I’m going to build, having a rough timeline is useful for setting expectations.
In order to meet the above goals, we don’t need exact estimates. Here’s the granularity that I like to use (also referred to as “t-shirt sizing”):
- XS: tasks that take less than a day
- S: a couple of days, no more than a week
- M: several weeks
- L: several months
- XL: several quarters
The above generally assumes 1 engineer working on a project. In practice, as part of this exercise we’ll identify which pieces can be parallelized. Then we can adjust our wall-clock estimate based on project staffing.
Of course, some kinds of work can’t be easily estimated. Exploratory work, where you’re working in a new codebase, or hunting for a bug, or doing some kind of novel project, will usually defy estimation. That’s fine! This is more relevant to work where you are already familiar with the systems involved.
Okay! Now that I’ve gotten the long-winded parts out of the way, let’s break down the formula. Credit to my former coworker Alex Cebrian, from whom I’m stealing these tips:
List all the tasks related for this feature. Be as specific as you can, as you would break them into branches.
Assign how much time you think you would need to spend on each task with 1 day minimum. Nothing should be more than 3-4 days, if it is, it should be broken down even further.
Go back to whatever number you assigned on (2) and double it… Really.
Build a dependency graph between tasks. This will help you identify what can be parallelized.
Have you thought about time for code reviews? Go back to (3) and add 30% more, minimum one day.
Have you thought about time for testing? (Both unit tests & manual end-to-end testing.) For features which need end-to-end testing, add at least 1 day each.
…and that’s it! I can’t stress enough how important steps #3 and #5 are, really, even if the estimate you end up with seems excessive. In practice, I’ve found that this approach does a good job of accounting for all of the unexpected problems that crop up in real software development. Did you need to do a minor refactor to add your new feature? Maybe you discovered a pre-existing bug that needed to get fixed? Or did you CI pipeline break just as you were ready to roll out your feature for testing? Those kinds of issues are entirely normal, so having a buffer for your “unknown unknowns” is really useful.
Okay. Now you have an estimate. What do you do with it?
This depends on your organization’s culture around estimation, project planning, and roadmaps, as well as what stakeholders are involved. Maybe you just share this with your manager, or perhaps you need to communicate this with other teams as well. The most nerve-wracking software estimate I’ve been asked to provide ended up being passed along to our CEO.
That probably sounds a lot scarier than it needs to be. I’ve most often seen these estimates being used to evaluate tradeoffs: “If we build Product A, it might take several months. But we can build Product B in a couple of weeks. Or we could build Product C, which will still take my team a few months, but we can unblock the other teams in about two weeks, and then we can develop in parallel with client engineers….” If your product managers or designers or executives are gung-ho about Product A but would still be happy with B or C, this lets them make more realistic choices about which direction to pursue. Crucially, in order to make those decisions effectively, your estimates don’t need to be precise; they just have to be accurate relative to each other.
This “formula” definitely isn’t scientific, but it doesn’t need to be. Hopefully, it gives you a starting point the next time someone asks you, “So how long will that take?”
Thanks to Laura Lindzey, Peter Lyons, Venkatesh Srinivas for their feedback on a draft of this post.