Managing technical debt by Chris Willmott
With the talk primarily aimed at those in technical roles, I'll be providing a number of practical methods to use when managing technical debt. About half the talk will be things we can do as developers to quickly identify then reduce the impact of technical debt, and half will be around how to explain technical debt to non-technical stakeholders.
Hosted by Alex Cachia, codeHarbour provides an opportunity for discussion and a platform for digital presenters to get their technological ideas out there to the people who need to hear it.
12. Like energy, problems are not destroyed, only moved
You can’t make your journey faster without taking risks
Hacks and shortcuts are not the same as improving efficiency
20. Future you* loves documentation
Verbosity is your friend, leave shorthand to the build
Comment your code with WHY not what or how
Include documentation in peer reviews
Include risks when quoting
Identify and document common debt patterns
Have conversations, draw diagrams, be brief
22. Over engineering! We don’t like talking about it.
Find the balance - good enough is usually ok
Arm’s length future proofing - be careful
Avoid writing code for hypothetical eventualities
Focus on now
Make future-proofing a tangible requirement
Technical debt describes the outcome of what is in effect a contract between current stakeholders and future stakeholders of a project - you are borrowing time or cost from your future selves.
In exchange for a quicker, faster result now - you almost always create more work at a later stage (due to having “thrown together” a temporary fix).
If you take a shortcut, without taking into account the longer term effects - it can come back to bite you.
In practice, I’m sure you’ve all been there. The client:
wants a new feature by the end of the week
wants their system ready to use month early
doesn’t have the budget to build a full feature now
What do we do here? Well, often, this is where compromises need to be made.
Important to accept that on most projects, some technical debt is an inevitability.
The trick is to make sure you know about technical debt, plan for it, and to make all other stakeholders stakeholders aware of it. Today I’m going to be sharing some tips and tricks for doing just this.
Technical debt describes the outcome of what is in effect a contract between current stakeholders and future stakeholders of a project - you are borrowing time or cost from your future selves.
In exchange for a quicker, faster result now - you almost always create more work at a later stage (due to having “thrown together” a temporary fix).
If you take a shortcut, without taking into account the longer term effects - it can come back to bite you.
In practice, I’m sure you’ve all been there. The client:
wants a new feature by the end of the week
wants their system ready to use month early
doesn’t have the budget to build a full feature now
What do we do here? Well, often, this is where compromises need to be made.
Important to accept that on most projects, some technical debt is an inevitability.
The trick is to make sure you know about technical debt, plan for it, and to make all other stakeholders stakeholders aware of it. Today I’m going to be sharing some tips and tricks for doing just this.
Technical debt describes the outcome of what is in effect a contract between current stakeholders and future stakeholders of a project - you are borrowing time or cost from your future selves.
In exchange for a quicker, faster result now - you almost always create more work at a later stage (due to having “thrown together” a temporary fix).
If you take a shortcut, without taking into account the longer term effects - it can come back to bite you.
In practice, I’m sure you’ve all been there. The client:
wants a new feature by the end of the week
wants their system ready to use month early
doesn’t have the budget to build a full feature now
What do we do here? Well, often, this is where compromises need to be made.
Important to accept that on most projects, some technical debt is an inevitability.
The trick is to make sure you know about technical debt, plan for it, and to make all other stakeholders stakeholders aware of it. Today I’m going to be sharing some tips and tricks for doing just this.
Technical debt is much like financial debt, it’s where the term comes from.
With financial debt, the currency is cash - you borrow money that you later need to pay back. E.g. spend money on your credit card now and pay it back later.
It costs you more in the long run, as there is a cost of borrowing.
With technical debt, the currency is time and effort.
You can receive an “advance” on your project functionality; but the cost in the long run is more time needed later to go back later and replace the temporary fix.
We can extend this analogy - to compare different financial borrowing:
If you take on a car finance plan, you plan ahead and accept the additional cost, and build it into your budget for the total cost of ownership for the vehicle.
Compare to a payday loan. One payday loan may not be a problem, but if you borrow every month from your future self, every pay day you’ll then have a shortfall - meaning you need to borrow more. This is an uncontrolled and unsustainable cycle, and can lead to much bigger problems.
In development, the more hacks and shortcuts you take over a long period of time, the more and more work will be needed to bring the project back on track.
Technical debt is much like financial debt, it’s where the term comes from.
With financial debt, the currency is cash - you borrow money that you later need to pay back. E.g. spend money on your credit card now and pay it back later.
It costs you more in the long run, as there is a cost of borrowing.
With technical debt, the currency is time and effort.
You can receive an “advance” on your project functionality; but the cost in the long run is more time needed later to go back later and replace the temporary fix.
We can extend this analogy - to compare different financial borrowing:
If you take on a car finance plan, you plan ahead and accept the additional cost, and build it into your budget for the total cost of ownership for the vehicle.
Compare to a payday loan. One payday loan may not be a problem, but if you borrow every month from your future self, every pay day you’ll then have a shortfall - meaning you need to borrow more. This is an uncontrolled and unsustainable cycle, and can lead to much bigger problems.
In development, the more hacks and shortcuts you take over a long period of time, the more and more work will be needed to bring the project back on track.
Let’s look at another analogy of how technical debt is created - Imagine you’re in charge of building a house.
You’re almost done, you have some nice walls, windows, but no roof yet. But then the owner comes along and says he needs the house to have a roof by next week because he wants to start decorating the walls and putting soft furnishing inside.
You don’t have time to build a proper roof, but you tell him you can knock something together with timber and tarpaulin, it’ll keep the rain out for now.
You warn him though, the roof will need to be replaced later - it’s only temporary - and to do this, it will take longer and be more effort in the long run than it would have done to put the proper roof on to begin with.
This is because when you come back to it months later, you’ll need to:
Reassemble your construction team
Gather all the tools
Remind the team of the architectural plans
Move all the furniture out of the way again
Cover the wallpaper
Take the temporary roof apart
ALL before you can resume work to build the proper roof.
This extra work is the cost paid later of having had the temporary roof.
The owner may have had solid commercial reasons for needing the temporary roof - and the benefit of having it may have outweighed the cost.
The danger would have been if had not been warned of this back at decision-making stage.
Most of the time, there are no shortcuts to solving a problem. You can never destroy energy, it just moves. Same with problems. If you hack it, you move it elsewhere in space-time.
So, assuming the most suitable plan has been agreed for a project, there is rarely room to introduce a short-cut (or hack) without having a knock-on effect later on.
This is like when your sat nav has already given you the fastest route; you can’t usually make your journey any faster without risk. Yes, you could break the speed limit, or turn right on a left-turn only junction, or drive across the bus lane - but you risk getting a speeding ticket, messing up your car, or worse causing an accident. It isn’t usually worth the risk!
BUTThis is not to be confused with finding a more efficient route part way along the journey. If you find they have just finished the new bypass that your Satnav doesn’t know about - brilliant, take this route, there’s no negative fall out. You save time and everyone’s happy.
In the real world - maybe you found there’s a new AWS tool just out, that perfectly handles a big chunk of functionality you now don’t need to write - WIN.
Most of the time, there are no shortcuts to solving a problem. You can never destroy energy, it just moves. Same with problems. If you hack it, you move it elsewhere in space-time.
So, assuming the most suitable plan has been agreed for a project, there is rarely room to introduce a short-cut (or hack) without having a knock-on effect later on.
This is like when your sat nav has already given you the fastest route; you can’t usually make your journey any faster without risk. Yes, you could break the speed limit, or turn right on a left-turn only junction, or drive across the bus lane - but you risk getting a speeding ticket, messing up your car, or worse causing an accident. It isn’t usually worth the risk!
BUTThis is not to be confused with finding a more efficient route part way along the journey. If you find they have just finished the new bypass that your Satnav doesn’t know about - brilliant, take this route, there’s no negative fall out. You save time and everyone’s happy.
In the real world - maybe you found there’s a new AWS tool just out, that perfectly handles a big chunk of functionality you now don’t need to write - WIN.
So, what can we do as developers and professionals in this industry to identify and reduce the risks that come from Technical Debt?
The first step is awareness.
Know that TD is inevitable on commercial projects. Commercial restraints on time and budget are almost always driving factors. So; how to control it?
Some things to keep in mind:
Think commercially
Build contingency
Document risk
So, what can we do as developers and professionals in this industry to identify and reduce the risks that come from Technical Debt?
The first step is awareness.
Know that TD is inevitable on commercial projects. Commercial restraints on time and budget are almost always driving factors. So; how to control it?
Some things to keep in mind:
Think commercially
Build contingency
Document risk
Learn to think commercially, and from a client perspective.You may know the correct way to do something, but this is about:
knowing when to compromise;
OR
if it is not your choice, when to flag risks.
When you compromise, do it knowingly and make the stakeholders aware of it. Understand that time pressures are not there for no reason - your client’s whole business may rest on it.
As a developer - you are in an informed position, it’s your responsibility to empathise with the commercial pressures that mean this compromise has been requested, and to impart knowledge to the project manager and/or client of what options there are and associated risks.
Try to understand WHY this shortcut needs to be taken. Use this to inform what solution you come up with.
We have a tool in our team called the ‘Hack Scale’ - a useful mental guide. In any situation, we make a judgement call on how ‘hacky’ to make a solution. And if we’ve done something very hacky, as a rule we aim to either mop up the mess immediately (e.g. we’ve hacked something in on live - go back and add it to the codebase later) or, otherwise make it clear to our client we’re doing a dirty fix and it will need to be looked at later.
Learn to think commercially, and from a client perspective.You may know the correct way to do something, but this is about:
knowing when to compromise;
OR
if it is not your choice, when to flag risks.
When you compromise, do it knowingly and make the stakeholders aware of it. Understand that time pressures are not there for no reason - your client’s whole business may rest on it.
As a developer - you are in an informed position, it’s your responsibility to empathise with the commercial pressures that mean this compromise has been requested, and to impart knowledge to the project manager and/or client of what options there are and associated risks.
Try to understand WHY this shortcut needs to be taken. Use this to inform what solution you come up with.
We have a tool in our team called the ‘Hack Scale’ - a useful mental guide. In any situation, we make a judgement call on how ‘hacky’ to make a solution. And if we’ve done something very hacky, as a rule we aim to either mop up the mess immediately (e.g. we’ve hacked something in on live - go back and add it to the codebase later) or, otherwise make it clear to our client we’re doing a dirty fix and it will need to be looked at later.
Build contingency into your own estimates.
When you spec and quote work, build in contingency time in your estimates, to refactor; or at least, write documentation. You need to include them in your estimates because these tasks can rarely ever by knowingly billed for.
Adding this in, is like a savings account. Every sprint, save 2 hours for refactoring. (This helps control the debt on an ongoing basis).
Because TD is inevitable. Allow time to manage it.
Example:
Client wants to get something live quickly, because they need it tomorrow. So you skip your usual deployment and testing procedures and you pop in the code on live. If you think this will take an hour; quote two. Then spend the second hour mopping up - e.g. adding your code back into your repo; or whatever else you need to do to help future-you avoid coming unstuck! (which leads me conveniently, to…)
Build contingency into your own estimates.
When you spec and quote work, build in contingency time in your estimates, to refactor; or at least, write documentation. You need to include them in your estimates because these tasks can rarely ever by knowingly billed for.
Adding this in, is like a savings account. Every sprint, save 2 hours for refactoring. (This helps control the debt on an ongoing basis).
Because TD is inevitable. Allow time to manage it.
Example:
Client wants to get something live quickly, because they need it tomorrow. So you skip your usual deployment and testing procedures and you pop in the code on live. If you think this will take an hour; quote two. Then spend the second hour mopping up - e.g. adding your code back into your repo; or whatever else you need to do to help future-you avoid coming unstuck! (which leads me conveniently, to…)
Documentation is really important
- write down you reasons for making decisions, and flag risks in writing
- this covers you, and (assuming the client is shown these risks), covers your company too.
- help your future self or other future devs: comment your code too!
Document your own problem-solving patterns. Why did you choose to this? What were the risks? What other options did you rule out? It may not reduce the actual debt, but can help explain or understand the debt in the future.
As a developer - you are in an informed position, and have a role in this problem. If you are quoting or speccing work, always include risks documented at quoting and speccing stage.
Carry out retrospectives after every shortcut. (Even just a 10 minute note-taking session). Keep a risk register of known issues in a project that might cause problems later - note these in your CRM, project management tool, or by email - wherever appropriate. Consider making a standard place within your team, if there isn’t one already. Make these notes both in dev language and client language. This helps future you and the future client!
Documentation is really important
- write down you reasons for making decisions, and flag risks in writing
- this covers you, and (assuming the client is shown these risks), covers your company too.
- help your future self or other future devs: comment your code too!
Document your own problem-solving patterns. Why did you choose to this? What were the risks? What other options did you rule out? It may not reduce the actual debt, but can help explain or understand the debt in the future.
As a developer - you are in an informed position, and have a role in this problem. If you are quoting or speccing work, always include risks documented at quoting and speccing stage.
Carry out retrospectives after every shortcut. (Even just a 10 minute note-taking session). Keep a risk register of known issues in a project that might cause problems later - note these in your CRM, project management tool, or by email - wherever appropriate. Consider making a standard place within your team, if there isn’t one already. Make these notes both in dev language and client language. This helps future you and the future client!
A quick mention here to the other side of this coin: The polar opposite of technical debt is over engineering!
This is when the solution that is designed is actually far more than was needed for the project.
Sometimes it is accidental - we want to prepare for every eventuality, and design a robust system - forgetting that every time you try to make it easier for future-you, it takes you longer now. If you find yourself trying to prepare for scenarios you don’t know if you’ll need, or may never happen - you might need to reconsider your approach.
It’s usually ok to make something GOOD ENOUGH - and document it.
Going back to our house analogy; if your client asks for a bungalow - and you made sure they DEFINITELY only wanted a bungalow - avoid the temptation to build foundations for a 3 story building based on a “what-if?”. Discuss it with the client, and make sure they know that if they do decide to add another storey later, they’ll need to re-do the foundations.
You are opting to do a quicker/simpler route now with the known risk you might need to do more work later.This is a form of intentional technical debt. ...
A quick mention here to the other side of this coin: The polar opposite of technical debt is over engineering!
This is when the solution that is designed is actually far more than was needed for the project.
Sometimes it is accidental - we want to prepare for every eventuality, and design a robust system - forgetting that every time you try to make it easier for future-you, it takes you longer now. If you find yourself trying to prepare for scenarios you don’t know if you’ll need, or may never happen - you might need to reconsider your approach.
It’s usually ok to make something GOOD ENOUGH - and document it.
Going back to our house analogy; if your client asks for a bungalow - and you made sure they DEFINITELY only wanted a bungalow - avoid the temptation to build foundations for a 3 story building based on a “what-if?”. Discuss it with the client, and make sure they know that if they do decide to add another storey later, they’ll need to re-do the foundations.
You are opting to do a quicker/simpler route now with the known risk you might need to do more work later.This is a form of intentional technical debt. ...
What is intentional technical debt?
It’s extremely valuable, e.g. in a new software build, to reduce the time-to-market. It is even perfectly logical, in some cases, to create technical debt by design. We know that time and cost are always there, acting as restrictions on what we can do.
Many of you will know about MVPs; we also have been known to build prototypes and “paper cup” products. These can save huge amounts of time now, and have massive benefits which almost certainly outweigh the knowledge that we’ll need to rebuild things later. It allows:
Testing the market
Being quick to market
Getting feedback
Lower upfront cost
Identify changes or improvements
What is intentional technical debt?
It’s extremely valuable, e.g. in a new software build, to reduce the time-to-market. It is even perfectly logical, in some cases, to create technical debt by design. We know that time and cost are always there, acting as restrictions on what we can do.
Many of you will know about MVPs; we also have been known to build prototypes and “paper cup” products. These can save huge amounts of time now, and have massive benefits which almost certainly outweigh the knowledge that we’ll need to rebuild things later. It allows:
Testing the market
Being quick to market
Getting feedback
Lower upfront cost
Identify changes or improvements
How to get clients, and often also members of your own team (e.g. project managers, salespeople) to understand all this, and be on board with it.
Related to the idea of Think Commercially: Be empathetic, rather than annoyed and angry. Often, it’s no one’s fault - it’s just business. If you recognise the predicament that someone is in, it will make it easier for them to also see your perspective too.
Try to negotiate getting a view on the bigger picture. Get them to let you in on their longer-term plans. It will help you reduce technical debt, because you as a dev can see what’s coming and make choices in an informed way.
Learn to speak in their language. They probably don’t understand or have any interest in the technical problems you have; so keep your language high level and simple. Only add technical details if asked.
When you flag risks, try to quantify what you are saying. Rather than saying “I can fix it now, but be warned this will cause problems later.” It is much more helpful to say “I can do a temporary fix which will take me 2 hours - but to fix this properly we’ll need to come back to it later. I’ll put a ticket in for this with a ball park of 10-12 hours, we’ll need to scope it out properly and include it upcoming sprint. Can you make sure the client knows this?”
How to get clients, and often also members of your own team (e.g. project managers, salespeople) to understand all this, and be on board with it.
Related to the idea of Think Commercially: Be empathetic, rather than annoyed and angry. Often, it’s no one’s fault - it’s just business. If you recognise the predicament that someone is in, it will make it easier for them to also see your perspective too.
Try to negotiate getting a view on the bigger picture. Get them to let you in on their longer-term plans. It will help you reduce technical debt, because you as a dev can see what’s coming and make choices in an informed way.
Learn to speak in their language. They probably don’t understand or have any interest in the technical problems you have; so keep your language high level and simple. Only add technical details if asked.
When you flag risks, try to quantify what you are saying. Rather than saying “I can fix it now, but be warned this will cause problems later.” It is much more helpful to say “I can do a temporary fix which will take me 2 hours - but to fix this properly we’ll need to come back to it later. I’ll put a ticket in for this with a ball park of 10-12 hours, we’ll need to scope it out properly and include it upcoming sprint. Can you make sure the client knows this?”