Every once in a while, I’m reminded that one of the most important tasks in software development that most developers never learn to do is to estimate projects. Interestingly, rather than drawing from other disciplines to teach people how to produce better estimates, the industry has shifted to management techniques that assume that estimates are going to be embarrassingly wrong.
So, since the topic has come up a couple of times in the past few weeks, I wanted to centralize my thoughts, in case they’re useful to someone else.
Estimating or Guessing
To start off, let’s be clear that a project estimate isn’t hearing a quick description of the finished project and picking a number that “sounds about right;” that’s a guess. There are cases where guesses are acceptable, and your guess might be right, but estimates are something different.
Let’s do the dumb “the dictionary defines…” thing, here, borrowing from Wiktionary.
estimate (third-person singular present estimates, present participle estimating, simple past and past participle estimated)
To calculate roughly, often from imperfect data.
To judge and form an opinion of the value of, from imperfect data.
Those are basically the same thing in different contexts, and I hope it shows the distinction between estimating and guessing. Your estimate would be the correct answer, if you had better information. Your guess would probably not change.
While, again, guessing is fine in certain environments, it has a huge weakness: To try not to over-promise, workers (especially software developers, in my experience) tend to try to find some magic multiplier that will turn their fantasy number into a valid number. It doesn’t work, but that doesn’t stop people from hoping to make the proposed time-frame long enough to sound credible, but short enough for the investment to sound like a good bargain.
In my experience, these factors come in a small handful of varieties, some more legitimate than others.
- After reviewing the plan, you can point to the places where the project has a lot of uncertainty that could go horribly wrong, and don’t think that there’s any way to measure that impact without doing the work. For example:
- If you need to integrate with a third-party service that’s still under development, you’re going to spend an unknown amount of time testing with your counterparts and rewriting code as the target moves.
- If you need to optimize an algorithm to trim requests below a certain threshold, you can calculate a lower-bound for the run-time, but time spent actually trimming time can easily hit a point of diminishing returns.
- You’re including overhead of work that you don’t personally do, but is an unavoidable part of the project. I’ll talk about this more, later.
- You haven’t the foggiest idea of what’s involved in this project, so you picked a number out of a hat and threw in a fudge factor, just in case you’re wrong; you’re probably also planning to work late when the deadline approaches. This is the situation described before, where developers tend to just find a compromise between sounding appealing and sounding possible.
- You don’t trust the other party to uphold their end of your agreement, so you’re just flat-out assuming that you’re going to need to do everything multiple times.
Uncertainty in the plan is almost always a legitimate reason to “pad” a schedule. They’re localized on the schedule and have specific justifications, so it’s possible to isolate that part of the project.
Overhead—design, management, testing, debugging—is also generally going to be legitimate, and probably even a good idea, as long as you understand the different roles involved in the project and which need to be part of your estimate.
You see the “fudge factor” in cases where the developer doesn’t understand how to build a real estimate. You’ll see people talk about “rules” of multiplying all initial guesses by two or three. It’s basically an admission of being far too optimistic as well as ignorance of scheduling, so it’s probably best to steer clear, when you can. It’s a step away from “it’ll be done when it’s done.”
Finally, trust is, as they say, a two-way street. In one direction, you have developers padding schedules because they believe that management or the customer is going to change the scope or even the nature of the project, meaning that someone will need to scrap or rework a fair amount of existing work. In the other direction, management or customers might push to pad the schedule (or might budget for your schedule as if it was several times larger), because they don’t trust the developer(s) to do the right work. If you’re adjusting the schedule because of a trust problem, you need to build trust, or your schedules are always going to leave someone looking foolish.
Note, by the way, that Agile development processes have tried to take trust out of the process, by shifting the focus of planning to “sprints,” when developers just try to get through as many tickets as possible, and then use that data point to predict what will happen during the next sprint. In doing that, however, it also mostly eliminates the idea of rigorous estimates in favor of gut reactions.
As I said about guessing above, there are contexts where guessing is fine, and Agile development processes are usually one of them. Just be mindful about what you’re doing and the risk that’s introduced.
Now that we better understand what not to do and why we might care about estimates, let’s talk about how to put a credible estimate together. Improved estimates are important, because reliably getting work done on time helps to fix the trust issue discussed above.
Divide and Conquer
That all said, the way I build my own estimates to increase the chances of it being correct is to recursively break tasks down with best-case and worst-case estimates, until the worst-case estimate is no more than a few hours long, since just about anybody is going to get that scale right, even if it’s just a guess.
That maximum-size time (of a few hours) is based on projects that are likely to take an on-one-hand number of worker-months, and so should probably be adjusted if that’s not the likely scale. Otherwise, you’re mapping out hours on a twenty worker-year project or on a weekend hack, which is either a waste of time or futile. To adjust, if we figure that three months has around five hundred work hours in them, you’re talking about your smallest unit being a bit less than 1% of the guessed-at size of the whole project.
Looking for the worst case keeps you honest and reminds you about all the little tasks you were going to just assume happened magically. Don’t skip that part.
A plan might look something like the following excerpt. Let’s say that the project is a traditional blog.
|Task Name||Best Case||Worst||Actual||Ratio|
|Index||👇2 h||👇5 h|
|👆 List Posts||30 m||1 h|
|👆 Paginate||1.5 h||4 h|
|Create Post||👇21 h||👇26 h|
|👆 Implement Default Editor (Scaffolding)||0 h||0 h|
|👆 Evaluate Rich-Text Editors||16 h||16 h|
|👆 Replace Default Editor with Rich Text||2 h||3 h|
|👆 Validate Input||2 h||4 h|
|👆 Preview Post||1 h||1 h|
|👆 Save Post||0 h||2 h|
|Edit Post||👇1 h||👇6 h|
|👆 Load Existing Post to Create Page||1 h||4 h|
|👆 Overwrite Existing Post on Save||0 h||2 h|
|Display Post||👇2 h||👇7 h|
|👆 Convert Internal Representation to HTML||0 h||1 h|
|👆 Insert CSS Classes into Post||1 h||4 h|
|👆 Show Post in Context||1 h||2 h|
|Add Comments||👇3.5 h||👇6 h|
|👆 Show Existing Comments for Post (No Threading)||1 h||1 h|
|👆 Create Comment Form on Post Page||2 h||4 h|
|👆 Save Comment Associated with Post||30 m||1 h|
I didn’t bother to break up Evaluate Rich-Text Editors, because (a) this isn’t a real project, (b) breaking it down would probably just mean listing the candidates, and (c) it’s not out of the question to say “after I’ve spent two days on this, I’m just going to pick whatever I’ve seen that looks best.”
Anyway, this project outline gives us a fifty-hour prediction. As tasks are completed, fill out the actual time spent in the fourth column, as honestly as possible.
Account for Overhead
Next, take your development-time estimate and put together a 2:1:3 schedule of design/architecture time, development time, and quality assurance/debug time. I forget where I got that guideline from, but it’s basically fixed overhead that you don’t want to think about up-front, and I’ve never seen anybody cheat that ratio. You can push that work around—like having the development team use test-driven development—and an internal project can often afford to ship incomplete. But as a sellable product, you need that design and test time, even though it feels wasteful.
That is, for the blog plan described above that’s planned to take fifty hours, the design time is going to be approximately one hundred hours, and testing/debugging time is going to come in at around one hundred fifty hours, for a total of three hundred worker-hours to make this a polished product.
Well, that’s not actually entirely true. That sixteen-hour step to evaluate rich-text editors isn’t a development task, even though a developer is going to do that work. Instead, it’s a design task that almost certainly incurs no QA time. So as you get better at this, you might say that the real development schedule is thirty-four hours, with sixty-eight plus sixteen hours of design time, and a hundred and two hours of testing and debugging.
As you work, you then track your low-level estimates, in order to forecast how you should adjust them in the future. Divide the worst-case estimates by the actual time spent. Take the average of those ratios—that’s not quite mathematically valid, but it’s close enough—and use that final ratio to adjust the sub-task estimates on the next project.
Note that this isn’t a “fudge factor” like the above. This is a recognition that you’re still learning to get the small estimates right, so this is correcting for your bias. As you go through more projects, you’ll notice that the ratio gets close enough to one-to-one that you can stop correcting for bias.
Don’t stop tracking the bias, though. If it starts drifting, you’re going to want to know that.
Yes, you’re thinking that this is much more work for a proposal than “eh, sounds like a nine-month job to me,” but it’s work that makes it easy to get estimates pretty close to the actual work that’ll be done, and also quickly see how any scope changes are going to impact the schedule. That builds everybody’s confidence, which is helpful.
Because this gives you a good view on the cost of features, a process like this also helps argue for and against work based on the return on investment, which is more useful than just arguing that a project will be “good” for the product.
However, like I hinted a couple of times, this process doesn’t mesh well with Agile-style project planning, because Agile is built around the idea that long-term estimates are going to be wrong, so take all of this with a grain of salt for a modern office. I suspect that there’s probably a way to fit the two worldviews together, but I haven’t gotten it to work, yet.
Credits: The header image is untitled by an unknown PxHere photographer, released under the terms of the Creative Commons CC0 1.0 Universal Public Domain Dedication.
Tags: techtips programming management