As I described in Under pressure, a way to avoid stressing yourself, your management, your team, and your resources is to stay flexible, and only make promises when necessary (typically, when obligated by a partner or customer). When a promise is necessary, only commit to a scope and timeframe in which, short of extraordinary circumstances, you can deliver on-time and as expected. But how do you determine the appropriate scope and timeframe?
Most project managers and engineers use some form of estimation to determine the appropriate scope and timeframe for an obligation. Since experienced folks know estimates are notoriously inaccurate, they add buffers. However, what’s the right amount to add? Or should you multiply by some factor? There are old rules of thumb (“double the estimate!”), but they seem like sorcery, not science.
To produce estimates you can depend upon with buffers that are sensible, you need to understand why estimates go wrong, how to correct them, what role buffers actually play, and how best to use them. As I revealed in I would estimate, there are simple, straightforward ways to produce accurate estimates, even for inexperienced engineers, and those methods have gotten even easier with Kanban and work tracking tools like Jira or Azure DevOps. However, did you know there are three different kinds of commonly used buffers, but only one is needed for accurate estimation? Surprised? Curious? Shocked that anyone cares? Read on.
Please note that much of what I cover around estimation and buffers is applicable to project management in general, not just software engineering. Also note that computing estimates is time consuming and should only be done for work that you are obligated to deliver within a timeframe for a partner or customer.
I’m in love with the modern world
Before we get to the three different kinds of buffers, let’s quickly recap accurate estimation and update it for modern methods. While there are many estimation techniques, the most accurate ones use past completion rates to forecast future completion times. The key is associating an upcoming work item with a similarly sized item you’ve done before and then believing that the new item will take a similar amount of time. The biggest common mistake is not trusting the estimate.
Modern estimation methods rely on three assumptions:
- Feature teams work together on features.
- Features are broken down into smaller tasks (the smallest features being a single task).
- Tasks take roughly the same amount of time, on average (typically a few days, even for inexperienced engineers who lean on teammates for help).
With these assumptions and readily available historical data from Kanban boards and work tracking tools, like Jira or Azure DevOps, you can make accurate estimates.
- Compute the rate at which your feature team completes tasks (tasks per day). For Kanban boards, simply count the number of tasks that your team finishes in a fixed time period (like four weeks). For Jira or Azure DevOps, you can query the number of tasks that your team completes over that period. Then divide the number of tasks by the number of days (including weekends), and you have your rate. (When your team changes size or otherwise shifts significantly, recompute your rate.)
- To estimate how long a feature will take, estimate the number of tasks contained in that feature and divide by your team’s task completion rate. That’s it. (If you aren’t using continuous deployment, then you’ll also need to tack on deployment time.)
Note that vacations, team size, engineer experience, live site incidents, and bathroom breaks are all accounted for in the task completion rate. If you’re unsure how many tasks are contained in a feature, use planning poker or, better yet, design the feature at a high level and count the tasks.
Once you have your estimates, perform the most difficult step: believe them.
I talk about modern estimation in more detail, account for feature creep, and even provide handy spreadsheets in my book, Agile Project Management with Kanban.
Three different ones
If you can quickly and easily make accurate estimates, why would you need buffers? To answer that, you need to understand the three kinds of commonly used buffers.
- The first kind of common buffer is used to ensure engineers stay busy, and it’s not a time buffer. Instead, it’s a backlog of work items with fleshed-out designs and broken-down tasks ready to go. Engineering time is valuable. You don’t want engineers sitting around idle. Having a buffer of work ready to go keeps everyone productive.
- The second kind of common buffer is used to correct bad estimates. Typically, bad estimates are made based on hunches, without the benefit of historical data. No one should estimate this way. However, bad estimates can be corrected by multiplying the original estimate by the amount it’s been off so far. Basically, you buffer assuming however slow you’ve been so far is the pace you’ll maintain. Of course, you’d have a more accurate estimate from the beginning if you’d used your historical completion rate (see the previous section).
- The third kind of common buffer is used to account for the last mile of variation. Even when a feature is ready to deploy, last-minute hijinks can cause delays. Unlike the previous kind of buffer, which acts as a time multiplier, this buffer acts like round-off error. If your estimate puts you delivering in the first two weeks of the month, commit to that month. If your estimate puts you in the latter half of the month, round up to the following month to account for any surprises at the end. This is the only kind of buffer you should add to otherwise-accurate estimates.
For more about the dangers of untasked engineers, read Idle hands.
Believe me when I tell you
There’s no reason to apply magical buffers or factors to your engineering estimates. Not only are they unreliable, they also can fail to hold people accountable for poor estimates and cause lax behavior. Instead, compute your feature team’s actual task completion rate, break down your features into tasks, and then estimate feature completion by dividing your tasks by your completion rate. If your completion date falls in the first half of the month, milestone, or sprint, commit to that period. If it falls in the second half, commit to the following period. That’s it—no magic.
Unfortunately, people still do believe in magic. That’s nice for Disney, fairies, and Santa, but has no place in engineering. When your estimate based on historical data tells you you’ll finish in three months, believe it. There are no miracles. Working weekends won’t help significantly, especially since pressure and sleep deprivation result in poor decision making and faulty workmanship. Remember that you worked hard on past projects, just like you’re working hard now. If it took you three months in the past, that’s how long it will take in the future.
Trust your teammates, your data, and yourself. If you really must move up timelines, reduce the scope or complexity of the project instead of second-guessing your estimates. Sure, you might impress management with your aggressiveness today, but they’ll remember you disappointing them far more tomorrow. Be a professional. Be an engineer. Use data and become a person and team your partners and customers can trust and rely upon.
For more on working weekends, read Marching to death.
When breaking down a feature into tasks, which level of granularity do you have in mind? Is a task the minimum amount of code that can go in a pull request and be deployed? Or is it that doesn’t matter as long as the team keep using the same granularity?
Tasks should roughly the same size and represent a small enough unit of work for teammates to wonder what’s wrong when they sit idle. For most teams, that translates to tasks taking less than five days.