Finding Time for Tech Debt Installments
Addressing technical debt in growing teams is a challenge, and the first step is finding the time.
No matter how experienced the engineering team you work for, the codebase age or technologies used - there will always be some level of technical debt, i.e. there will be some things that could be improved. Its impact is hard to predict, but the symptoms will likely include difficulties adapting to changing requirements, slowdown in delivery of new features and decreased job satisfaction for software developers.
Technical Debt is admittedly a widely overloaded blanket term, and I'm shamelessly using it here to mean "everything that's wrong with out codebase".
If you find yourself struggling with these symptoms, as many growing developer teams do, it's time to come up with a strategy for addressing your technical debt. The exact course of action suitable will depend, but what's certain is that you'll need time to execute.
Carving out time to work on purely technical tasks with elusive, indirect business value in an environment that values shipping above all is tough. It can be a challenge to explain the benefits (current or potential in the future!) of a code refactoring or switching libraries to a fellow developer from a different domain, let alone a colleague from product or business. Addressing technical debt can easily become a people problem more than a technology problem - which might be at the heart of why many teams struggle with it. By selecting an approach to time allocation with the right set of trade-offs for your organisation, you can mitigate some of these issues.
All together now
One such way it is to schedule recurring periods (e.g. every 6th week) where all engineers across the organisation work together on technical tasks instead of their usual team's backlogs. I came across this approach in two mid-size startups I worked for, and both teams called it Engineering Weeks.
I'm not sure how widespread this practice is across similar companies, and couldn't find anything on this topic online - if your team does this, I'd love to hear about it.
The idea of Engineering Weeks seems particularily attractive if you're normally working in autonomous feature teams because it promises some great benefits:
- Gives control over prioritisation to engineers who can decide what's the most imporant technical work to be done
- Allows devs from different feature teams, specialising in the same technical area to work together
- Makes it easier to comprehensively address issues spawning the whole codebase
- Engineers from different teams working together enables cross-team knowledge sharing
- It's an opportunity to build the team spirit of the entire engineering team, as opposed to only within feature teams
In practice, the effectiveness of this approach varied, but ultimately the idea was dropped at both companies. Some of the challenges we faced included:
- Difficulty with "selling" to the rest of the organisation the idea of halting all feature work for a week. No matter how much work we put into explaining the efficiency wins and translating technical jargon into more relatable terms (and believe me, it was a lot of work) - we never managed to get rid of the "engineering taking a break" optics expressed behind the scenes.
- The time allocation of a week, or even two weeks, proved to be insufficient to attack the really significant technical changes that we envisioned. The changes that benefited most from cross-team collaboration - enabled by the Engineering Week format - often fell into that category. Sure, you can carve out a section of a bigger problem to complete it during a single Engineering Week, but you'll lose all of the context and momentum before the next one.
- The fixed schedule was messing with feature teams' delivery rhythm. Need only one more sprint to ship that great new feature? Sorry, gotta wait a week. Fighting bugs after the release? Bad luck, your engineers won't be there next week. Even though the schedule was set way up front, the teams ended up being surprised by the Engineering Weeks anyhow.
I don't think these challenges and my experience prove that this approach cannot work. If you have an experienced and self-driven engineering team with a depth of PM skills and allow for some scheduling flexibility it can likely be an effective technique. It could guarantee you have the time to address technical debt, while reaping some unique benefits. My hunch is that it would work best for small engineering teams - those that maintain systems which can still be meaningfully improved within a week via grassroots-driven initiatives.
Power to the teams
An alternative approach is to leave it up to the each feature team to allocate time for addressing technical debt. This may seem like a natural fit if you're already geared to trust autonomous teams to make the right decisions, but this setup presents challenges too.
Parts of the codebase that no team claims ownership of will never get the care they might require.
Wider changes that require cross-team collaboration will be hard to pull off due to mismatch in teams' current priorities.
This setup doesn't help with cross-team knowledge sharing and can be inefficient if multiple teams spend time solving the same problem internally, without coordinating.
It's likely that some teams will perpetually descope addressing technical debt, especially if the team lacks experienced engineering leads.
While not easy, these challenges can be mitigated. Dealing with ownership as well as driving cross-team technical projects and knowledge sharing is a subject for another blog post, so let's focus on that last challenge now.
Feature teams often use a prioritized backlog to figure out what to work on next. In an ideal situation, it contains the tasks that address technical debt, and those tasks eventually bubble up to the top of the backlog. In practice, these tasks are usually pushed down - by a new feature we need to get out fast, by a bug that just popped up or by "if we lived with this for so long I'm sure we can live for another month" mindset. The team will only get to address technical debt once its symptoms start to severely impact the team or the customers - and that's too late.
To help yourself avoid this fate you have to be explicit about the tech debt time allocation in the team. There are many ways to cut it, including:
- X% Engineer Time This is the approach I've encountered the most. Each developer is encouraged to spend a fraction of their time on technical work they themselves prioritise, whenever they feel they can. This puts a lot of pressure on individuals and often ends up being something way too easy to forget about or descope.
- Tech Fridays A dedicated time slot every week, for example half a day. Fridays, being often slower and cut short work well for this. Having the calendar event each week makes it easier to remember and develop a habit of thinking about tech debt continuously. The downside is that half a day is a painfully short timeslot, and anything more than a simple refactoring or library upgrade can easily spill over.
- Cooldown Weeks - It's a twist on Engineering Weeks that's optimised for a single delivery team working in sprints. I think that the term originates from Basecamp's Shape Up, although the idea itself is likely older. After completing a sprint, intead of jumping to a new a one, the team spends a week on various maintanance tasks. It doesn't need to be technical debt only, e.g. preparing for next sprint, researching, bugfixing etc. are also good candidates for Cooldown Weeks. Instead of prioritising work as a team like during the sprint, each team member is in charge of their own priorities.
The strenght over the cross-org Engineering Weeks is that each team can find a way that works for them and fits with their release cycle and composition. It will however require additional cross-team roles, infrastructure and initiatives to coordinate bigger tech projects, facilitate knowledge sharing etc. - especially for bigger engineering teams.
It also doesn't necessarily need to be either-or - you can run Engineering Weeks on top of the team's own time allocation schemes - but you might start to lack time to work on the backlogs.
Regardless of which approach you choose the ultimate success will require the engineering leaders, within teams and the organisation, to be actively involved.
They need to facilitate healthy accountability, so that people or teams can and do broadcast an account of what they did to address technical debt and how long it took. Accountability doesn't need to equal responsibility for mistakes, but having clear and open communication about what was done and a dialog on how to improve.
Leaders also need to enable and push for visibility - it has to be clear to everyone how much of a problem technical debt is in different parts of the codebase and how much time is spent to address it.
Doing this reliably, sensibly and at scale is a huge challenge.
All this is just one small aspect of the entire behemoth of dealing with technical debt. It's a fascinating problem from the intersection of technical and organisational expertise, with real implications on the company's abilities to build products and its perception as a workplace. I'm looking forward to exploring this topic more!