As software developers, we always try to do our best to write clear, concise maintainable code. Programming is a craft and as craftsmen, we like to take pride in our work.
Unfortunately, in some cases, the most elegant solutions can take a little too long for some managers to stomach. It doesn’t always matter that the compromise will mean more work later on if the result is getting the project delivered on time.
It is these compromises that end up resulting in Technical Debt (or Tech Debt for short).
When I think of the causes of tech debt, it reminds me of a project in the first company I worked for. I had a very good Principal Engineer and Scrum Master on the team that taught me about the 3 legged stool.
When building software there is always 3 constraints that need to be considered:
If any of them are fixed then one of the other 2 legs is affected.
If the Time leg is fixed, such as having a tight deadline, then you either need to lower the quality of what you are producing or payout for more engineers to complete the project on time to the same high standard.
If the Cost leg is fixed, you again have the option of lowering the quality of your work or just taking longer to build it.
If the Quality leg is fixed, then it is either going to cost you a lot of money or take you a long time.
If either time or cost is fixed then it is nearly inevitable that the quality of the project is going to suffer as a result.
Unfortunately, in most companies, both time and cost are fixed. You not only have a tight deadline to complete the project but you also don’t have enough developers on the team to complete the work.
To try and get the work done in time we make little compromises here and there that become technical debt.
This could be:
// TODO: Insert witty tech debt joke here
The obvious impact of tech debt is that you are putting off work that is going to come back and bite you at a later date.
There are however more subtle impacts of tech debt that you need to take account of.
As I mentioned, we are craftsmen by trade. Now imagine an expert carpenter, who is proud of everything he makes. He not only selects the best woods but also uses the best tools and makes sure his creations are made to the highest standards. He wants to show the world what he has made as he has put his heart and soul into it.
His boss then tells him that there is a special request for a table that needs to be made. He only has 2 days to do it and because the budget is tight he has to use plywood and MDF instead of the premium wood he usually uses.
As this is a one-off the carpenter obliges and builds the table in 2 days with the wood provided. He isn’t happy with what he has made. It certainly isn’t going to be going on his Instagram page but at least it is done.
His boss however has other plans. Seeing dollar signs (or Pound signs for my fellow Brits) in his eyes he asks the carpenter to build a few more. After all the profit margins are a lot higher on these cheaply made tables.
Before he knows what is happening the carpenter is spending all his time building poor-quality tables and he is hating his work. On top of that, one of the first few customers isn’t happy as a leg has fallen off his table and the carpenter now has to fix that as well.
Our code might not fall apart if it is poorly built but it will result in more bugs that take time away from producing quality code. It becomes a vicious cycle that snowballs into features taking longer and longer to deliver.
As we aren’t able to produce the work that we know we are capable of this also affects team morale as well.
Obviously, in an ideal world, we wouldn’t produce any tech debt, but things are never ideal and we have to make compromises somewhere.
Most companies don’t have any processes in place for managing tech debt and it is usually up to the engineering teams to come up with their own systems.
If your team has a lot of tech debt to manage then here are some techniques you can use to get ahead of it.
When time is short we sometimes knowingly miss out on some unit tests or documentation. When this happens it is important to write this down somewhere so it can be picked up later on.
Personally, I prefer to add a ticket to the backlog tagged as tech debt. Not all managers will like this and you might need to create a separate board somewhere for tech debt tasks.
If you don’t write it down it will get forgotten about.
This should be at the back of your mind whenever you are writing code. For small tech debts, you can usually fix them while you are adding to that piece of code.
In the past, I have added a function to a class only to find that the previous developer didn’t write any unit tests. You could do the same and add on top of the tech debt but provided the class isn’t too big it is better to write the missing unit tests while you are there.
If you have created a ticket in the backlog somewhere for the tech debt then it is important that the team make time to estimate them.
There are a few things you need to consider when estimating tech debt.
Teams should have a meeting at least once a month if not every 2 weeks to go over the tech debt backlog and prioritise the work.
One option for tackling your tech debt backlog is to pull in items during sprint planning.
There is a downside to doing this though. If engineering doesn’t have much leverage over what work is pulled in then it is always going to be a negotiation whether to work on tech debt or not.
It is usually easier to allocate 10-20% of every sprint to dealing with tech debt. Try to under-commit on the work that you bring in each sprint and then any additional time left in the sprint should be to tackle items on the tech debt backlog.
This is good for small to medium pieces of tech debt that can be completed in a day whereas large pieces will need to be brought into the sprint as normal. If you have particularly large pieces of tech debt such as a platform migration then it is usually better to plan these quarterly.
📝 Article - Imaginary Problems Are the Root of Bad Software. This is an interesting article about what really causes bad software. I remember one of the first projects I ever worked on for a company was full of different tech. The developers considered it a CV padding project.
👾 Software - GB Studio. I spent a large part of my childhood playing Tetris and Micro Machines on my Gameboy. Now anyone can create Gameboy games with a drag-and-drop editor.
📝 Article - I Don’t Need Your Query Language. SQL is actually a very good query language once you know it well. I used to love being able to query JSON data in S3 using SQL. I agree with the author here, I would rather use a language I know well than try and learn one for a particular database.
📝 Article - Google Tells Employees to Stay Away from Its Bard Chatbot. Even though ChatGPT and the range of other AI tools can be a great productivity boost, caution should be taken. Even Google advises employees against using their chatbots due to security concerns.
🎬 YouTube - How to Build a Project That Will ACTUALLY Get You a Job. If you are trying to get a job as a software engineer but lack a degree and experience then you need a way to show off your skills. The best way to do this is by building a project but not all projects are created equal.
Starting something, as imperfect as it may be, already makes you better than the vast majority of people, who never start anything.