How To Reduce and Report Uncertainty In Features
To reduce uncertainty, we need to identify its sources. I identified six sources.
Why Reduce Uncertainty?
By uncertainty, I mean the risk of being delayed more than expected. I won’t focus on other uncertainties, like whether the feature solves or doesn’t solve the users' needs.
Uncertainty affects the whole system and team, not just the current task. In a previous article, I showed how increasing task uncertainty increases the team’s Lead Time.
How do we reduce the uncertainty of developing a feature?
To reduce uncertainty, we need to identify its sources. I identified six sources:
Break current functionality
Dependency task hell
Developing too much or too little
Confusing UX
New technology
New problems
Each source requires different approaches to reduce the risk.
Finally, I added a bonus section on how to report uncertainty: Status Hill.
Sources Of Uncertainty
Break Current Functionality
Adding a new feature means adding more code. Every developer knows that adding more code means adding more bugs, especially if we edit shared modules, functions, or components.
By following standard best practices, we reduce this risk:
Make sure to tick all the boxes and reduce the uncertainty.
Dependency Task Hell
Tasks in software engineering don’t share the commutative property; when we change the order, we don’t always get the same result. Therefore, we need to be careful when splitting a feature into subtasks.
A good split is essential when multiple people work on the same feature.
To reduce the uncertainty, take care of the following:
Make an implementation plan and identify parallel and sequential tasks.
Vertical slicing. Integrating backend and frontend is a common source of delays.
Mythical man-month. Adding more developers doesn’t mean faster development.
Too Much Or Too Little
Scoping a feature well is critical to developing the right amount so that users get value and the team doesn’t spend too much time.
We need to watch out for the following:
Define the desired scalability and performance of the feature.
Define which edge cases are handled and which are not.
Define the level of error management and how to fail gracefully.
Do not assume—ask questions.
Define the UX and UI requirements like animations, responsiveness, supported devices, and browsers, …
Validate the UX design (or mockups) before starting implementation.
Confusing UX
What if we launch the feature and no user can navigate it? It might happen if the development team works in an ivory tower, never talking with users.
There are known best practices to avoid this:
Agile methodology and continuous feedback.
New technology
If the feature requires a new library or a new third party, we must analyze the library carefully.
Ideally, we get help from people who have used it. But we also reduce uncertainty by creating a proof of concept with the new technology before developing much of the feature.
We want to avoid having developed half the project just to realize that the third party works in a way that we need to rewrite everything or notice surprise costs that double the expected budget.
A New Problem
A new problem is something that has not been solved before by that team or project.
If we find a new problem, we should prioritize it to find red flags early.
We should avoid falling into a fat tail distribution: something takes ten times longer than expected. If we think that’s the case, we should raise a red flag and maybe reduce the scope of the feature.
Algorithm To Reduce Uncertainty
As a general rule of thumb, we should first consider the sources that might introduce more uncertainty and work our way to the ones with less.
Don’t take this diagram at face value; reality is never so linear. We might want to start implementing parts that we know have no uncertainty. Or we might start with an implementation plan first and then discover we need a new technology.
The order is not as important as understanding where the uncertainty comes from.
Two Examples
Let’s look at some examples and the primary sources of uncertainty.
Adding a light and dark theme
I will assume that the team will implement both themes using CSS variables—that’s how I would do it—.
In my opinion, there is one primary source of uncertainty: will this break the current UI? To help with that, we can split the feature into two main tasks:
One is to reimplement the current UI with CSS variables without allowing colors to be set directly.
The other is to implement the second theme.
Let’s look at each source of uncertainty as well:
Break current functionality
If we break the current theme, it could delay the whole feature.
We can add screenshot testing.
We can also split the work into two consecutive projects. First, implement the current theme with CSS variables that are agnostic of the colors, and then add the other theme.
Dependency Task Hell
It might be counterproductive to start working on a new theme before we have moved the current theme to use CSS variables.
Too much or too little
Make sure the requirement is to support only two themes.
Confusing UX
The new theme should be tested with real users.
Users should be able to change the theme themselves.
Does the project default to the user’s device theme?
New Technology
Using CSS variables is using a new feature. Therefore, it should be done first.
If we use UI libraries, we must ensure it supports the new theme.
New Problem
If the team has never implemented two themes, this is a new problem for them, and they should start with a simple PoC to understand how it works on a small scale.
Adding Real-Time Data
Let’s imagine we are developing a social media app and want to add a real-time feed.
I see two primary sources of uncertainty in this feature
The definition of scalability and performance.
We can define the required scalability and performance by looking at the current and expected usage in the upcoming months.
Solving a new problem or new technology.
We can develop a PoC or MVP of the feature behind a feature flag.
Let’s dive into the details of the uncertainty:
Break current functionality
We need to make sure the initial loading works as it does now.
We should have e2e and unit tests for all the current loading functionality.
Dependency Task Hell
Instead of parallelizing the backend and frontend, we could build an MVP of the feature without considering any performance or scalability issues.
Once we know the connection works, we can work in parallel on the backend and frontend.
Too much or too little
How many concurrent users do we have, how many posts per minute, etc?
We need to look at the baseline to understand what the feature needs to support.
We don’t want to overengineer, but we also don’t want to overload the server and fail to deliver the feature.
Is this an opt-in feature for users?
Confusing UX
How will the new posts appear? Should we implement nice animations?
New Technology
Are we going to use a library? Which one? Has anyone on the team used it?
We should use the new library when we implement the MVP of the feature.
New Problem
Is it the first time that we will add a real-time feature? If so, there is more reason to start with an MVP or a PoC of the feature.
BONUS: Status Hill - Reporting Uncertainty
The best way to report uncertainty is a concept developed by Basecamp called Status Hill:
Instead of reporting how many tasks are done and how much time is missing—which is always inaccurate— the development team reports which unknowns have been solved.
Once the team is in the downhill part, estimations are more accurate and can be considered by management for further planning.
Thanks to Elina for giving the idea for this article and then reviewing it!
Job Board
Senior Frontend Engineer - Rec
Remote - USA. $130k - $160k
Lead Software Engineer - Counterpart
Remote - USA
Senior Software Engineer - Web
Remote - Europe or Asia