Delivering Customer Value meanwhile maintaining a Manageable Technical Debt
Explained using System Thinking
I do not know if it is your situation, but during all my engineering career technical debt had always been present. In the beginning, it exploded in my face without noticing, after gaining experience, I started to be aware of it and be able to tackle it but it is still a challenge.
This post is about understanding how Technical Debt impacts Delivering Customer Value and how to manage it. 😄
My relationship with Technical Debt after the years
My perception of technical debt has changed dramatically from the early days of my career to today.
I started thinking that I was a bad developer because I was not doing clean code, I was not doing it perfectly, and that’s why we had technical debt because we weren’t good enough.
Technical Debt caused bad emotions in me, it impacted my self-worth, I felt a lot of impostor syndrome and I was always anxious to learn more to not create bad code that translated to Technical Debt.
It also impacted the product and, in consequence, the end-user. Because of the bad code? No, because we weren’t shipping meanwhile looking for perfection. Preventing us to learn with the customer feedback loop to improve the product, preventing the customers to use a product that solves their current problems, etc.
When you accept you cannot have 0 technical debt, you start looking in the right way.
Technical Debt is a tool. As a tool, you need to learn to use it properly.
Modeling the Customer Value Delivery as a System
I discovered the Insight Maker tool that helps you create systems to perform simulations. It’s super cool! That’s why I decided to create a system in order to explain how things connect and impact Customer Value.
As with all Systems, it is an imperfect representation of reality and it only helps me to share how Delivering User Stories, Technical Debt, and investing in Improving the Systems relates to Customer Value.
You can find the System Modeled here. But let me explain what each figure means (for full info you can check the tool reference here).
Here are the steps I took to get into that System
Each box meaning
Stock
Stocks store a material. For instance, a bank account is a Stock that stores money. In our case, in software, it’s not tangible material but I hope you can follow my explanation.
Product Backlog
represents the Product Kanban Backlog. As a simplification, I assume each user story produces 1 Customer Value.Customer Value
is the sum of all User Stories Value.Technical Debt
is the sum of technical debt we introduce meanwhile delivering value.Continuous Improvement Tasks
represents the Engineering Kanban Board with the tasks to reduce technical debt.
Flow
A Flow moves material between stocks. For instance, in the case of a bank account, you could have an inflow of deposits and an outflow of withdrawals. In our case, moves for example User Stories into Customer Value.
New User Story
represents when the Product Owner adds a task into the Product Backlog.Development
represents the process of taking a User Story from the Backlog and push it to production.Introducing Technical Debt
is the process of, meanwhile developing, we introduce some technical debt.Add Continuous Improvement Task
is the process of identifying a technical debt to improve and create a task to remove that technical debt.Decrease Technical Debt
represents a refactor in the code to remove the technical debt.
Variable
Variables are dynamically calculated values or constants. In the bank account model, you could have a Variable representing the interest rate. It could be a fixed value or be governed by an equation that changed over time.
Effort
is how difficult it’s to develop user stories. Depending on the quality and technical debt, you need more or less effort to develop a task. With 0 Technical Debt, you have 0 effort, and with a huge technical debt, you need a lot of effort to develop a task.Team Capacity to Improvements
is the percentage of engineers dedicated to picking the Improvement Tasks and reducing the technical debt.Quality
is the amount of refactoring we do to not introduce too much technical debt meanwhile delivering. 100% quality means 0 technical debt introduced. 0% quality means full technical debt introduced (whatever that means)Investing in TechDebt
is the amount of new tasks * the percentage ofTeam Capacity to Improvements
Running the simulation! ⛹🏻♀️
Let’s imagine we start a new Product, we want to deliver an MVP as soon as possible because we want to verify that there’s a market fit. Lucky for us, around day 25, we were able to say that yes! It’s a viable product 😁
Simulation 1. Maximum Quality to keep the Technical Debt at 0 🤓
Simulation Parameters
Quality: 100%
First Day Investing in Continuous Improvement: N/A
Team Capacity in Improvements: N/A
This is an unrealistic and naively approach that by dedicating the most effort to quality in the software, we can keep the technical debt to 0.
In this scenario, by day 20, we deliver 10 points of User Value by having 0 technical debt! Ouwho! Isn’t it awesome?
Different problems
Why are you investing that amount of energy in keeping the Technical Debt to 0 when you didn’t verify the product yet?
Could you go faster to production introducing some technical debt?
Simulation 2. 0% Dedicated to Software Quality, Full Speed Ahead! 🏎
Simulation Parameters
Quality: 0%
First Day Investing in Continuous Improvement: N/A
Team Capacity in Improvements: N/A
Sadly, this scenario might be more realistic. Not 0% quality, this is to show the extreme case, but the poor quality it’s more common (or at least I have got this feeling based on my experience).
It shows different things:
In the same period of time, we deliver more value
We introduced different technical debt
After day 45, the technical debt kept increasing making the development harder and harder, and given a point, we were unable to deliver value to the customer.
Scenario 3. Okay, not full speed nor full quality. A 50-50
Simulation Parameters
Quality: 50%
First Day Investing in Continuous Improvement: N/A
Team Capacity in Improvements: N/A
It shows different things:
In the same period of time, we deliver more value than the first scenario (full quality) but less value compared to the second scenario (0 quality).
We introduced half of the technical debt compared to the 0% quality scenario!
After day 90, the technical debt kept reached the point we were unable to deliver value to the customer.
🤔 Strange. But we’re dedicating time to make clean code and good architecture, not the 100% but some!
Scenario 4. When Technical Debt is no longer manageable, then we start with the “Full Refactors” killing Continuous Value Delivery
Simulation Parameters
Quality: 50%
First Day Investing in Continuous Improvement: 65
Team Capacity in Improvements: 50%
This can be seen as a continuity of scenario 2. Given a point, we cannot deliver value as faster as before, so, we need to dedicate a huge amount of effort for a long period of time to put Technical Debt in a manageable state.
We have different problems with this approach of waiting too much to start improving the systems:
We need to move considerable team members to remove the technical debt during a long period of time
Since we have high technical debt, the team that keeps working in user stories still have a high effort to produce value and then are half of the team
The team is able to reduce the technical debt, but it takes almost the same time it took to get to an irreversible state to start delivering value again.
Scenario 5. Start investing in Continuous Improvements Earlier
Simulation Parameters
Quality: 50%
First Day Investing in Continuous Improvement: 30
Team Capacity in Improvements: 30%
This scenario is proof that dedicating some team capacity to improve the systems and, therefore, reduce the technical debt, helps to maintain a reasonable continuous delivery of value.
Managing Technical Debt with Continuous Improvements
70% - 30% Rule
Dedicate 70% of the team capacity to customer value and 30% to continuous improvements to maintain technical debt in a manageable state.
I highly recommend base this rule on time instead of tasks. Why?
Let’s imagine we’re using Scrum and at the beginning of the Spring we decided to do 7 User Stories and 3 Improvement Tasks. Meanwhile, it seems correct, the variation of the task to the task might cause that we don’t handle well the technical debt.
Instead, I found that dedicating people to a set of Technical Tasks for a long period of time to work better.
In our case, we use Kanban, we are 6 developers and we work as Pairs. We decided that 1 pair will work fully on technical debt.
This model works well to use because we never stop shipping value to the customer and we keep the technical debt manageable.
How to make technical debt visible
We have different techniques to make so:
As part of Architectural Decisions Records
Do a brainstorming session with the whole team to talk about the technical debt they know and place it in the Effort Matrix (see next section)
As Continuous Improvement Tasks in your Product Management tool like Trello or Jira
What should we improve next?
In case you have already identified the technical debt you have or the most relevant to you, you can make some questions to know what to improve next:
What can do your development experience better?
Can make the development of our current user stories better?
Has it high-value impact on the technical debt?
Is it a low-effort change?
Summary
Even dedicating time and effort to software quality, technical debt needs to be addressed with dedicated time and effort that do not produce customer value
If you take too long to start dedicating this effort, you enter in the “full rewrite/full refactor” phase where teams stop producing customer value because they need to decrease the technical debt by a lot
By introducing small effort at the beginning (not from start), you can maintain a manageable level of technical debt that won’t stop the continuous customer value delivery
Interesting related posts
Books
The way of modeling the problem as a System comes from this book, Thinking in Systems. This book helps you understand the world as Stocks and Flows + Feedback Loops. It’s just awesome how a simple concept as the book shares can explain much in the world we live in.