Is Technical Debt Really A Technical Problem?

I often hear the term “tech debt” kicked around but I don’t think it’s well understood.

What is tech debt?
Ward Cunningham created the metaphor to help explain the process of delivering early which leads to the need to go back and “finish” the product. In general, tech debt comes from releasing a product before it is completely done – it’s the gap between what’s done and what needs to be done. That gap should be visible and understood by the dev team and the Product Owner. In fact, the team & PO should agree that there is tech debt before deciding to release; some gaps will be acceptable and some won’t.

What tech debt isn’t
Tech debt isn’t an excuse to write bad code. It may be incomplete because there are parts of the puzzle that are lower priority, e.g. it’s more important to get feedback on the high priority parts first. It may be that parts of the Definition of Done aren’t finished because you’re going to sit with some early-release users to observe them using it so documentation can wait, for example. But poorly written code is just that: bad code, not tech debt.

Accruing interest
One of the reasons that debt is a good metaphor is the concept of interest – the longer you have debt, the more interest you accrue and the longer it takes to pay off. With software development, the longer you leave a product “in debt” the harder it is to build on top of it.

If, for example, there are no automated tests then changes to that piece of code become riskier because you can’t easily check for unintentional consequences (aka bugs). If you now decide to write automated tests for this subsequent change, then it will take longer (cost more) because you’re starting from scratch rather than adding to existing tests.

Good and bad debt
The debt metaphor continues to work when thinking about when to incur it: there are times when it can make sense to incur debt, e.g. buying a house. An important part of intentionally incurring debt is having a plan for paying off the debt.

Deliberating incurring tech debt is often driven by deadlines, or at least the pressing need to “ship now and deal with the consequences later”. This tends to come from (or, at least, through) the PO so the cost should be obvious. The team should ensure the PO knows what is outstanding and therefore an informed decision, weighing up costs and benefits, can be made. The absence of that shared knowledge and conscious decision-making leads to surprises and mistrust; remember that the Definition of Done is an agreement between the team and PO – it’s a common understanding of what “done” means, so it’s important to be clear when a release is falling short of that bar.

Have a plan
An important, and often overlooked, part of responsibly incurring debt is having a plan to resolve it. It’s all too common for tech debt to be forgotten or ignored, but pretending it doesn’t exist won’t make it go away. If it’s important to release something now, before it’s finished, then make sure the tech debt items are identified and added to the backlog … but then also agree when they will be addressed.

Of course plans can change, but start with a target and ideally that’s as soon as possible, while the context is still fresh in everyone’s minds. The plan could also be that some items will not be done; my preference would be to have those items in the backlog and then mark them as “Won’t Do” (or whatever the equivalent is for your situation) so there’s a reminder of that decision. (This isn’t for any “blame” – it’s so I don’t forget and later end up wondering why things aren’t done.)

Review your tech debt
I don’t mean review the backlog items representing your tech debt; I mean think about the cause(s) of your debt. Include tech debt in retrospectives or continuous improvement discussions: what led to incurring the debt and was it avoidable. For example, could the scope have been reduced so that the team could have fully completed something smaller rather than 90% finishing it all?

As part of reviewing what led to the tech debt, it’s also useful to identify any patterns in which items are incomplete, i.e. are the same corners being cut on a regular basis? If so, should we just remove them from the DoD and then add what’s needed for specific features.

Is tech debt a technical problem?
If you’re wondering “Who ‘owns’ tech debt?” then I believe it is the responsibility of both the dev team and PO – there should be a shared need to minimise tech debt, both accruing new debt and paying off existing debt. The are many reasons why, amongst them: the health of the product, the wellbeing of the team, and the speed of future development.

I’ve seen some teams have a formal 80:20 split of time in a sprint, trying to balance “product work” and “technical work” (I’m not a fan of this approach but I’ll save that for another post) so they might wonder whose time does tackling tech debt fall into? Well, if there was no tech debt that would mean the product work was completed as per the DoD, and therefore that was all done in product time. So if there is tech debt, that means some of the product work was not completed, and therefore when tackling the tech debt it should be seen as product work, the same as it would have been in the first instance. Personally, I would prefer to call it product debt because that’s what it is, a deficiency in the product, but the tech debt term is ubiquitous … and I’d rather put effort into reducing it rather than renaming it.

Incurring technical debt is not necessarily a bad thing – there are times when making an informed decision to take on tech debt is the right decision … but there needs to be a plan to pay off that debt. Ignoring tech debt won’t make it disappear and eventually you’ll have to declare bankruptcy, i.e. the software has so much debt associated with it that the only way forward is to wipe it out and start again. Few organisations can afford to do that, so Product Owners need to prioritise tackling tech debt as well feature development.


Take Courage

Courage is the willingness to confront fear; one Scrum value says “The Scrum Team members have the courage to do the right thing, to work on tough problems”. It may not be “running into a burning building” courage, it can still be quite daunting to speak up when you feel yours is the lone voice or when stepping into unfamiliar territory.

For the upcoming hackathon, my fellow coaches and I have decided we’re going to spend a few days trying to better understand the developers’ experience by using some of the same tools and techniques. Why does this take courage? Well, some of us haven’t written code professionally in many years (~20 years in my case) and some of us have never been a developer, so we all have a lot to learn. Fortunately, as a strong team, we know we can rely on each other for support as we learn but it won’t all be “the blind leading the blind” – we have found ourselves a coach 🙂

We have the benefit of it being greenfield development (starting from a blank page rather than on top of legacy code) and the freedom of being our own product owner. It means we can focus on the things we want to experience rather than what we need to build; if we discover our current “product” (a slack bot to support team appreciation) doesn’t give us the learning opportunities that we want, we can chop and change it.

I expect it will be interesting to see many software engineering principles being applied in new ways, for example in my day change control was managed via sccs or vcs; these days it’s git. The rationale is the same, the operations are the same, but the commands have changed … and why did they decide to use push and pull counter-intuitively? 🙂

Just like the teams we coach, I’m sure there are things I’ll need to unlearn before I can learn the new approach.

Adapting Scrum

That’s not a typo in the title – I see lots of articles about adopting scrum (i.e. getting started) but I wanted to touch on adapting scrum, for those who have been doing scrum “by the book” and are wondering what’s next.

The most common start point for groups as they step into the agile world is scrum. It makes sense because the official scrum guide details many of the things which they need to do, which may well be quite alien to them, for example having regular retrospectives to look for ways to improve how they work. I’ve heard people use the analogy of learning ten pin bowling with “bumpers” to prevent balls from going into the gutter, however, even following the scrum guide word for word won’t prevent a team from encountering problems. Instilling the practice of retrospection should give teams a fighting chance at tackling those challenges, but there are no guarantees. It’s worth understanding that scrum won’t fix your problems – all it can do is shine a light on them, and then it’s up to the people involved to resolve them.

Over time a team becomes familiar with scrum’s pillars (transparency, inspection, and adaptation), values (commitment, focus, openness, respect, and courage), events (sprints, sprint planning, daily scrum, sprint review, and retrospective) and artefacts (product backlog, sprint backlog, and increment). Once they find a cadence that works for them, a team can become restless and wonder “what’s next?” – ideally their mindset of continuous improvement has the team looking beyond scrum.

One area I encourage teams to investigate is XP because scrum focuses on how teams can organise their work and deliver value when faced with complex problems – it doesn’t mention anything about software engineering, and that’s where Extreme Programming fits in. XP provides some concepts which will be familiar to scrum teams (iterations, stand ups, sustainable pace) but also some which are commonly associated with scrum and yet aren’t in the scrum guide, for example, user stories and velocity. Scrum and XP fit together so well there ought to be a name for it!

Just like scrum, XP can appear simple at first but (as claimed by some games) it takes a minute to learn, a lifetime to master! Some of the concepts seem obvious, maybe even redundant, and yet I have seen teams struggle to do them well – “Code the unit test first“, “All production code is pair programmed“, and “Refactor whenever and wherever possible” to name a few; “Simplicity” is maybe the hardest because any half-decent developer can write code which works, but producing clean & simple code takes practice.

Fortunately, unlike scrum, XP doesn’t say you have to do it in its entirety. It was created in the 1990s, so some specifics of XP could benefit from a revamp but on the whole the values, principles and practices would still be valuable to most dev teams. Take an agile approach: understand your needs, find a part of XP which might help, try it, then inspect and adapt. 🙂

It’s often about this time that I find teams want to try Kanban – it’s important that teams are doing it because they want to find better ways of working, and not because they think it’s a way to avoid the parts of scrum that they don’t like. Whereas scrum has “bumpers” which provide a lot of guidance on how to get started, kanban does not mandate any process – this means the team need to provide that discipline themselves.

The simplicity of kanban might seem like freedom or even anarchy, but I feel it is a lot more work – the team need to pursue incremental, evolutionary change, constantly looking for ways to improve the way they work. Moving from scrum to kanban should be an incremental process – scrum is a good starting point from which to evolve. This is scrumban – a hybrid of scrum and kanban, not (as some people seem to use the term) a lesser version of scrum.

Many scrum teams may have started incorporating elements of kanban without realising it, for example the board that most people associate with scrum is actually a kanban board. Visualisation is key in kanban, but as many teams are now working remotely diagrams and images are essential tools in sharing knowledge whether you’re a kanban team or not.

Hopefully, the team is still inquisitive and hungry to improve because there are many other areas to explore – the agile umbrella is quite broad, but there are also many things not considered to be “agile” which can prove fruitful; the two which spring to my mind are Lean and Systems Thinking because they can be the basis for expanding the way the team observes, comprehends and tackles problems.

Some people consider Lean to be part of agile, some people don’t, but regardless of that I think there is a lot to learn from it. I recommend starting with eliminating waste; for me, this opened a whole range of more areas to explore but even a superficial appreciation of the types of waste can help teams see ways to improve. The other principles should resonate with those experienced in scrum and XP: Amplify learning; Decide as late as possible; Deliver as fast as possible; Empower the team; Build integrity in; Optimize the whole. The fact that these same themes keep appearing in different forms should reinforce their importance; if your team struggles with any of these, I hope this will make you revisit them and try to find ways to improve.

Systems Thinking is an area that I am still exploring. (Realistically I’m still learning in all these areas but systems thinking is one I feel I have the most to learn.) I feel that if XP can take a lifetime to master then I need to become a cat in order to fully get to grips with systems thinking! Fundamentally it’s about understanding how everything is connected to everything else.

In scrum, for example, you may observe a challenge in sprint planning but it could be that tweaking the way the team do refinement will address it. Perhaps adding another refinement session will help… but that takes time away from the planned sprint work… so the team may need to reduce their commitment… but we have a deadline to meet so we can’t commit to less (if anything we’re being pushed to do more)… so instead we end up shortening the refinement session… so we’re less prepared for sprint planning… so our forecasts are worse… so our stakeholders push harder… and so on.

So for those who have been doing scrum “by the book” and are wondering what’s next, I think there are many options; I recommend looking at Kanban, XP, Lean and Systems Thinking as a start, but <coach_voice>it depends</coach_voice> – as always, every team’s challenges are different so understand your situation, where you want to grow, and then look for alternatives.

Don’t follow the book if it’s not helping you; maybe there are other sources that can help; maybe you need to create a cocktail from a few things. Not only are teams different, but a single team changes over time, so what worked for you last year may not be right this year. In fact, if you are striving for continuous improvement then working in the same way that you did a year ago should be an indication that you might want to think harder about how to improve in that area. And remember: not every change will result in an improvement; inspect and adapt, constantly.

Quality built-in

When you notice that the quality of your product isn’t a high as you’d like, what can you do?

It’s useful to start by understanding what quality means for your product: how is it defined, how is it measured, and what level is desirable.

For example, if your indicator is the number of “escaped defects” (i.e. bugs found in the customer-accessible environment) you probably want a very low number; zero is ideal but probably isn’t realistic – no matter how tight the controls are, some defects will escape. In fact, in a safe (non-life-threatening) environment, a few escapes may actually be desirable as an indicator that the controls are not excessive (i.e. wasteful).

But if you only have one metric, then you could end up focusing on that at the expense of everything else. If you only focus on preventing bugs you could spend a lot of time “gold-plating”, building far more than the customer really wants.

There needs to be one or two other metrics for balance, e.g. delivering on time (or improving the cycle time), automating as much as possible, reducing technical debt – again, it needs to make sense in your environment.

Once you have those complementary metrics in place, the question may arise: who is responsible for achieving them? In “traditional” software development there used to be a Quality Assurance team that were meant to catch all the bugs before the product was released.

The obvious problems with this are that it puts too much onus on the QA team and it’s too late in the dev process … oh, and anyone who has worked on a waterfall project will have seen that QA always gets squeezed by deadlines, so the all-important “final line of defence” has to make compromises.

It’s unfair to make the QA team solely responsible for quality when they only see the product when it’s finished – at that point, it’s very expensive to rectify a defect. Sometimes the escalating cost of fixes can lead to their prioritisation, delaying “cosmetic” defects, resulting in a bug backlog.

A better approach is to identify and tackle quality problems sooner in the development process. For an agile team, that means continuous testing, frequent feedback from the intended users, as well as code review, pair programming and other feedback loops. Quality is something the team “builds in” throughout their process; they seek to constantly improve the product they create as well as how they create it.

As far as bugs are concerned, I like the approach recommended by Yassal & Daniel Sundman: Fix It Now Or Delete It! If the bug has to be fixed now, then fix it; if not, then delete it.

I tend to believe there’s room for a little leeway: if it needs to be fixed ASAP but without disturbing the current sprint, then bring it to the next sprint planning… but if it doesn’t make it into that sprint then it should be deleted.

But quality is more than just removing (or better yet, avoiding) defects. If the team get feedback earlier then any changes needed in the design can be incorporated sooner changing direction to meet the users’ needs. The team should also be constantly looking for ways to improve how they work, i.e. retrospectives and/or kaizen. If the team can identify bottlenecks or waste in their process, then they can increase their throughput and maybe make their work more enjoyable.

Quality can mean many things; once you’ve defined it for your circumstances and identified how you’ll measure it, then ensure that everyone understands not only what quality is but also how everyone is involved in contributing it. (Ideally, the whole team have been part of those previous steps!) That could include writing automated tests for more than just the happy path, involving real users in providing feedback early and often, or participating in retrospectives to improve the way in which the team work.

But you’re not done yet – quality is a moving target. Once hitting the current target consistently has become a habit, then it’s time to expand your definition. If you start simply with just counting escaped bugs, then consider inspecting how long it takes to go from idea to released feature (“concept-to-cash”) – how can you go faster without the bug count creeping up? Hopefully, the answer will involve removing impediments, bureaucracy and other wastes but that’s a topic for another day.