7 strategies for measuring and tackling technical debt
In the previous post, we looked at 7 sources of technical debt. So how do we measure each of these to bring them to light?
- Bugs. Measure and shrink your cycle time from when code is first written until it is tested (TDD is perfect for this, of course). Treat open bugs as work in progress (WIP) — and too much work in progress is evil. Constantly measure and manage WIP down with strategies like bug caps (no new features until existing bugs get below a defined bar).
- Missing tests. Measure code coverage. Have a clear definition of “done” at each scale of your product: unit, feature, scenario, system. Treat units of code as incomplete until code, tests, and documentation are delivered as a set.
- Missing automation. Make build and deployment first-class features of your project. Deliver them early, and assume (like other features) that they will constantly evolve with sub-features over the course of the project. Measure time-to-build, time-to-deploy, and time-to-test — including human time expended each cycle — and then drive those numbers down by adding automation work to your backlog.
- Incomplete scenarios. Assign scenario ownership roles among the team. Have a clear definition of “done” for each scenario. Pre-release working scenarios to select customers as soon as possible, making special note of these bugs. And of course, minimize the number of scenarios each team focuses on at once (one at a time, if possible).
- Not understandable. Like most open source projects, generate docs directly from the code (literate programming), including why the code does what it does. Systematically conduct code reviews. If the team can’t afford to review every line, always review a sample set of functions from each developer and component. Ask reviewers to rate code for understandability, track this data in code comments or a spreadsheet, and add workitems to the backlog to clean up those most needing improvement.
- Not extensible. Encourage design pattern thinking. Buy your team a library of design patterns books
and posters
to help form that common vocabulary. Look at how open source projects tend to build big things out of many small, independent pieces — treat every component as a library with its own API and a clear (and minimized) set of dependencies.
- Not integrated. Minimize the number of branched codelines, whether they’re formally in source code control, done on the side for customers, or sitting on developer’s disk drives. Unintegrated code is debt — it has work and surprises waiting to happen. Strive for continuous integration. This isn’t to say don’t use branching — even the smallest project should think about their mainline model — but always keep everything in source control, then track and minimize the number of active branches.
There is a rich set of metrics here — # of active branches, # of dependencies per component and globally, time-to-build, code coverage %, # of bugs, etc. Taken together (literally, from a spreadsheet as a multi-value line graph over time), they can provide a rough index of the health of your project.
Some are more expensive than others to collect and track, and some are more valuable — so not all projects will use all of them all of the time. Smaller projects might want to just focus on one area (e.g. getting all tasks in a database, and keeping that number down).
Of course, putting too much weight on any one metric or set of metrics in a larger organization will cause the numbers to get “managed down” — regardless of the underlying reality. And don’t get too distracted by the numbers. Use the numbers as feedback, as signals to take action, and as evidence to identify and attack the current bottleneck in your process — not as a way to reward or punish individuals.
So how much debt has your project accumulated? What are your next steps to systematically pay off and keep down that debt?
- Login or register to post comments
- Read original article.
- Printer friendly version

