Since its re-opening a few years ago, I always enjoy driving over the east span of the Bay Bridge. The new bridge is open, airy, and stylishly built, in contrast to the old, stodgy, utilitarian former span. The bridge is also a staggering 25,000 percent over the initial budget estimate that was proposed and sold to voters.
Once you exit the Bay Bridge in Oakland, you immediately find yourself in a highway jungle known as the MacArthur Maze. In 2007, a catastrophic gasoline tanker accident melted down the 160 feet of the highway, and threatened to negatively impact Bay Area traffic for an uncertain amount of time. Amazingly, and much to the surprise of Bay Area residents, the lower span was reopened to traffic in one week, and the upper span was completely rebuilt and operational within a month.
Estimating both the time and cost to complete a task has been a continual challenge for engineering teams as long as I’ve been working in the industry. Coordinating the complex interactions and execution task sequencing across multiple tasks and people is a complex, ever-evolving challenge, and one that most teams struggle with daily. And the challenge is not constrained to solely software engineering. What tactics can we use to ensure our projects are more like the MacArthur Maze rebuild—on time and on budget—rather than like the Bay Bridge project?
Introducing MNRU: Mechanical, Normal, Risky, Unknown
I’ve used a very simple framework called MNRU in the past for coming up with task delivery estimates. Note that MNRU is not a panacea for all task estimation problems; it does not address task parallelization, for example, the way a Gantt chart would. But, it has helped me improve my own task estimates in the past.
The first step in applying the MNRU framework is to label every task with one of the four letters. This is how I generally interpret and apply those labels:
M: Mechanical. A mechanical task is one that is so familiar and known to you that you can visualize and plan every needed subtask down to the letter. And example of this would be: “In order to implement this task, I need to update the setFoo() method in Bar.java. In the third line of the method, I need to update the if() conditional check to account for an additional predicate.”
N: Normal. A normal task is one that you are very comfortable and confident in your ability to execute, but will require some slight investigation to double check your assumptions. For example, “In order to implement this task, the logic is dependent on the value of Foo in every Bar object. I know there’s a setFoo() method in Bar.java, so it’s very likely that’s the right place to start looking. It’s been a few weeks since I’ve touched this code though, so I’ll need to take a look to see if things have changed recently.”
R: Risky. A risky task is one that you do not have much visibility or confidence in. It will typically require consultation with other people and significant research. An example of this might be, “In order to implement this task, I need to make changes in the Ad Server. I know the Ad Server is split between Ad Mixers and Ad Shards, and I believe this change is on the Mixer. I think there’s a concept of a Filter in the Ad Server, and this change will require changes to an existing filter, or writing a brand new one. I need to talk to someone from the Ad Serving team to validate these statements.”
U: Unknown. An unknown task is something you have no context in, and will need to do significant discovery and research work to come up with a plan. For example, “In order to implement this feature, I believe I need to implement a Deep Learning model. I vaguely know that Deep Learning is a machine learning technique related to Neural Nets, but I’ve never taken classes on the topics, nor have any hands-on experience with these techniques.”
Asking yourself or other people what MNRU label tasks should be classified with better contextualizes how risky an estimate and project plan is, and provides you with more information about how to proceed.
Using Fibonacci Numbers for Task Estimates
Another strategy I like to use is to force coarse granularity of estimates for larger tasks. This is explicitly acknowledging and accepting that large tasks are much more difficult to accurately scope, and will encourage teams to decompose tasks into smaller, better understood ones, and therefore reduce risk in the project.
Allowing teams to only choose one of the Fibonacci number sequences for estimates (1, 2, 3, 5, 8, 13, 21, etc.) is an easy way to put this in practice. How well do we trust ourselves to differentiate between a 21-day task and a 22-day task? Much less than our ability to differentiate between a 1-day task and a 2-day task.
Applying MNRU to Engineering Projects
Once MNRU estimates and corresponding time estimates have been made in a project plan, I also like to use one of the following two approaches to further apply MNRU.
Apply estimate scalars to estimates, or intelligent sandbagging. By definition, MNRU creates clarity on how confident we are in a particular task’s certainty and risk. One simple way to incorporate certainty and risk into estimates is to apply simple scalars based on the label. For example, apply a 1.0x scalar for M, 1.25x for N, 2x for R, and 5x for U. Now, a risky task that we estimate at 3 weeks should have 6 weeks built into the project plan, to account for that risk. Feel free to start with these scalars, but also modify them based on your own observed results, such as changing U to 3x instead of 5x, for example. This is a more principled way of “sandbagging,” or applying buffer/margin time, into estimates, than applying a universal constant scalar for all tasks equally.
Set a maximum threshold for risk tolerance in a project plan. Another approach, one that I personally prefer more, is to state that there is a maximum threshold for risk that is allowed in a project plan until the project estimations can be trusted, and the team should be held accountable for the plan. For example, as managers or leads, encourage and mandate that teams decompose Risky and Unknown tasks into smaller pieces. As tasks are decomposed, continue to decompose further until each smaller task is either Mechanical or Normal in risk.
In my experience, applying MNRU has led to creating project timelines with higher confidence, predictability, and reliability.
If you’re interested in joining our engineering team, we’re hiring! Apply on our Careers page.