Making Time To Tend Code
A question that software developers everywhere struggle with is how to make time to get things done in their codebase. Agile approaches seem to be mostly about piling in more features. Any developer knows there’s a ton of work not directly tied up with these new features. Often it seems developers are left trying to beg, borrow or steal time to take care of tasks that are hard to explain to non-technical people with haphazard results. Being driven to deliver more features while sidelining their concerns has the effect of making developers feel like second-class citizens with no voice. Agile process being used as a stick to beat developers is a sad state of affairs but there are ways that Agile process can also be used by developers to create protected time for work they need to get done.
Codebases are in some ways like gardens, to continue to be fruitful, they must be tended with care. Garden plants don’t stay the same shape, as time passes they grow in all directions eventually dying back to make room for others. Code also grows in different directions over time and as patches of code start to yield less business value we need to consider removing them. To walk easily around your garden, you have to cut back stray branches and sweep up to keep paths clear. Like gardeners, software developers need time to prune sprawling code, thin out overcrowded components and tease out new services so they may flourish.
In my experience, Scrum-style planning tends to focus team effort on developing user facing features that can easily be explained to business stakeholders. Extending the gardening metaphor, the items that appear in our backlogs are like new garden features – plant a fruit tree so we have apples, install a shed so we can keep our tools safe, create a stunning herbaceous border in the front so we can make our neighbours envious, etc. Sprint planning doesn’t cover time for weeding the existing flower beds, raking up dead leaves, removing an ants nest that’s making the patio unusable. Developers need time to stay on top of technical maintenance alongside development of new features. Although a Scrum team should be able to add technical tasks to their backlog, typically the focus of a sprint is meeting the sprint goal, delivering all the shiny new features that will generate business value.
Developers often grumble that there’s not enough time in a sprint to stay on top of the technical tasks. I’m talking about things that no stakeholder will ask for. For example, tidying up deployment scripts, new browser VMs for testing, upgrading to the latest release of something. Nearly always code tending tasks can be deferred over delivering more features. When we decide to put them off, we may also be increasing the work needed to sort them out. Anyone who has ever had a lawn knows grass grows fast in the springtime – you need to get out with your mower every week or you’ll soon regret it. Leave the grass until it’s knee high, you have to use a strimmer. Strimming long grass takes a lot longer than mowing and leaves the grass looking roughly hacked back. Putting off care for your lawn turns a simple task into a laborious one.
To ensure more time is available to improve our software systems, developers may try to make code tending work visible to their business stakeholders as “technical stories”. We recently created a technical story to cover a rewrite of a stats pipeline to handle higher volumes of data. However, there are so many mundane tasks that it doesn’t make sense to expose a large stream of technical stories to stakeholders unless it’s going to seriously impact delivery of new features. Most Scrum teams have a bunch of technical tasks in their sprint backlog jostling for time alongside work on new features. When work on features and technical tasks is lumped together into a single line on a burndown chart and aggregated into team velocity, it’s really hard for any team to get the balance between these types of work right.
Inspired by a Kanban technique, separating out different Classes of Service for feature development over support changes, I encouraged our XP teams at Unruly to separate out different types of work on their team boards. This enables our teams to balance their capacity across the different types of work: features, tech tasks, support, research. Doing this helps us maintain momentum on all of these different types of work. Sounds a bit complicated? Making different kinds of work more visible helps us not to neglect one kind of work over another.
We use different colour cards to represent different types of work. We use white cards for stories and green cards for code tending work. We try to do refactoring as part of stories but sometimes we stumble across bigger issues that can be done later as green cards. How do we make time to do these green cards? Well the secret of XP is that we just do them. We only include work on stories in our velocity. Excluding green cards from our velocity means that it only represents our likely capacity for prioritising the new stories. Now we have time to keep working on a steady stream of code tending tasks. Our business stakeholders are happy with this because we keep delivering new features and they don’t have to wrestle with trying to understand the priority of the technical stuff that we need to do to maintain our codebase.
All of our teams use simple tracking mechanisms to ensure that we maintain a balance between new features and technical improvement work. One team does dot counting. Other teams keep an area on their whiteboard for tracking where their time goes. They have their own system of coloured magnets and hieroglyphs. These trackers are updated by the team at standup time so we spot if we’re not striking the right balance. We later take photos of them to review in our team retrospectives.
Each team prioritises their green cards weekly. To figure out which tasks are most important, we ask whether doing this work help us deliver value to our business in the coming weeks. As one of our team leads puts it “does this make our real days closer to ideal days?”.
Yes, there are busy times when we feel the right thing to do is deliver more customer facing features over technical tasks. But often our system will force us to put on the brakes. Neglecting technical tasks will eventually slow us down – our tests take longer to run, it takes more time to deploy, developer motivation is sapped. We may even lose developers who are fed up with working around an ageing technology stack.
Setting aside time to tend our code is essential for us to maintain fruitful software assets. Start by making technical tasks visible to your team. Prioritise these tasks so that the team works on the ones that will yield most benefit. At standup, consider as a team, what effort should be put on code tending tasks today. Keep track how much time you spend on code tending, this can help you strike the right balance against business facing features. Reflect together as a team on how code tending is going.
You may wonder whether putting prioritisation of technical tasks in the hands of developers leads to business priorities being ignored. We prefer to consider that our developers are taking on more responsibility and accountability for protecting our software as a business assets. We also find this way of working helps developers keep their code bases pleasant and easy to work in.