Tag Archives: agile

Measuring Technical Debt

Recently I saw a Twitter thread bemoaning the rise of ‘psychological safety’ as a phrase. Not because it isn’t important – it is – but because giving it a name has made it acceptable and risks giving a scapegoat to hide behind. There’s the possibility that just saying ‘My organisation / team doesn’t promote psychological safety’ makes it OK.

I have similar feelings about ‘Technical debt’. As a phrase in its original sense (the fact that not keeping code clean and deployable eventually incurs a real, financial debt that must be repaid), it is useful. But every non-startup I have heard of has struggled with ‘technical debt’ and it has started to be accepted as just something that happens.

Let’s not forgot that not all technical debt is bad. There can be good reasons for taking on debt, and in fact I’d actively encourage it in embryonic, experimental projects, provided it is monitored and quickly repaid.

But with excessive debt, a time comes when development teams become so crippled by the legacy code that progress slows to a snail’s-pace and further work becomes unacceptably risky. In these situations, where should you start with ‘debt reduction’? I’ve seen projects that have quickly spiralled out of control into a whole rewrite project, or worse the team can become embroiled in a long discussion about the best way to fix things.

One of the teams I work with was in such a state last year. In fact, it was worse than that. They actively did not know which products they had on live servers (these are all websites) and there were so many inter-dependencies between them that it was almost impossible to know where to start.

Fortunately, our boss understood the problem and was willing to give some time to sort it out. Together with the Product Manager and our Site Reliability Engineering team, I helped to set some goals for the team to start tackling the issue, without ending up rewriting everything. Our definition of what good looked like was:

  • No websites should be running on unsupported operating systems
  • All sites should be deployed through our CI pipeline
  • All code should be deployable at any time
  • Nothing should be deployed with a CVSS score greater than seven (still high, but a reasonable, measurable start)

(This may sound unambitious, but based on where we were starting from, it was a big challenge!)

The team then set about fixing up the most obvious candidate products.

We soon hit our biggest issue. With the team struggling to untangle the code – often written by contractors, and so completely unknown to the team – progress towards these goals was slow. It was also almost impossible to report on. Furthermore, because we didn’t even have a full list of products or which servers they were on, any measure of progress towards an end-point (such as burndown / burnup) would be meaningless. 

In SMART terms, we didn’t know whether our goals were achievable or realistic, and so we also couldn’t timebox them, which was unacceptable. It was clear we needed a way to measure and to report on the beast. This was not just for management. Part of our thinking was also that measurement would help morale in the team. Although at this early stage, they were pleased to have the opportunity to work on something that had been a pain for years, but it was clear that this would not last without regular celebration.

It was time for a creative solution. Inspired by both the term ‘technical debt’ and the product management prioritisation technique of asking stakeholders to vote on backlog items with money, I sat down with the team and we discussed which of the goals were ‘worth’ more, and put some values on them. We also took the opportunity to hold ourselves to account by putting a bit more rigour around the goals, for example, when we said ‘code must be deployable through our CI pipeline’ we specified ‘to live’, since deploying to UAT only might make the situation worse.  Similarly, to measure ‘deployable at any time’, we specified that there must always have been a live deployment within the last two months. If no development work had happened for the previous eight weeks, deploying an unchanged build would be fine, but at least demonstrates that rot hasn’t started to set in. It’s the little failures nobody notices while they have other priorities that tend to add up to debt later.

The result was our new list of problems and their debt value:

  • Websites running on unsupported operating systems = £25
  • Websites that couldn’t be deployed all the way to live via the CI pipeline = £50
  • Websites not deployed in the last two months = £20
  • Websites with a CVSS score that was 7+ or which was unknown = £40

This allowed us to take the list of products that we did know about and calculate our starting level of debt: £3535! This approach also meant that, as we uncovered new information (whether good or bad), we could show this by adjusting the debt amount. In fact, five weeks after starting, our ‘debt’ figure had worsened to £4015, as the team had learnt more.

But above all, it meant that we could show our progress graphically and set up a celebration point for the team whenever we had removed £1000 from the debt.

To get a bit more momentum around this idea, I also acquired a load of Monopoly money and displayed it in the office, so colleagues could see money moving between a ‘debt’ and ‘repaid’ pile whenever something was ticked off the list.

Technical Debt visualised as Monopoly money

This visualisation had a mixed response in the team. In all honesty, most developers were ambivalent about it, even if managers mainly liked it. It also had the slightly unforeseen difficulty in not being a great demonstration of continuous progress: The inter-dependencies tended to mean that the graph would go several weeks without many changes and then a big improvement as many products got deployed together. I’m not convinced that I ever managed to fully explain that that wasn’t a problem. If you try this in a similar context, I’d certainly recommend stressing that it shows repayment of whole pieces of debt, not progress through the work itself.

By the way, ‘repaying’ the debt wasn’t only a development job on this team. It was also a product management job as we managed to decommission a number of rarely- used websites. In those cases, we repaid all the debt on those products at the moment of decommissioning.

Recently, there has been an unexpected result of the graph. Remember that rule that everything should have been deployed in the last two months? In November and December, priorities changed, and the technical debt reduction work was paused (or rather, deprioritised) for a while. Due to this, and the fact regular deployments hadn’t been set up, the graph is now starting to head in the wrong direction, as deployments made in October start hitting the two month limit. This has served as a useful reminder that there’s still work to do if we aren’t going to have more problems in the future.

Debt graph

Are we aiming to repay the amount of debt all the way to zero? No, probably not. There wouldn’t be sufficient value in doing this. But monitoring this figure in the future should be a good mechanism to track where we are, and to ensure that the products are not allowed to become bad again, after all the investment we made during the latter half of 2018.

Direction, momentum and oil: Why software development teams are like bikes

I haven’t posted for a while on what I’ve been up to at work and there’s a good reason for that: the team I’ve been working with was pretty dysfunctional twelve months ago and I’ve been spending the last year trying to turn them around. In this post, I’ll describe that journey and why I’ve concluded that software development teams are like bicycles.

Context

I was first asked to spend a couple weeks in April 2015 working with Redgate’s SQL Monitor team as an external observer, finding out why their Project Manager was struggling and why the team was perceived as delivering slowly. In this environment, some of the team were even starting to leave the company…

A bit of background: the SQL Monitor project had been stopped for just over a year after the release of version 4 in January 2014. In the intervening time, no work had happened on the product, and the original team had disbanded. Many had gone off to do other things. In the meantime, revenue had continued to increase and so, in early 2015, the company decided to form a new team to continue that growth. The new ‘team’ (a mix of different people that had been cobbled together, most of whom had no experience on SQL Monitor) would work on one feature in order to get used to the codebase, while the company decided on what the further roadmap looked like. That didn’t sound like a team set up for success.

In my favour was the fact that the team knew they had a problem and so were prepared to work with me to address it. We didn’t have much time, though: the following week, two newly-hired developers were set to join them and we needed to make their introduction as good as possible. So, the usual advice that a Project Manager / Agile Coach should just start by observing the team went out the window. I had to act fast.

I started by organising a retrospective with the team to investigate their various problems. This was a fairly painful session, which I facilitated, using a fishbone diagram technique:

Fishbone diagram

As expected, there were a number of really fundamental issues here, mainly with the state of the code, but feedback was that it was quite cathartic for the team to see them written down in one place.

To summarize, this was a pretty bad situation: the team had no goals, no deadlines and were struggling to do valuable work. In other words, they had no direction or momentum and the bicycle chain wasn’t even allowing the different parts to work in concert.

Giving a direction

During the same week as that retrospective, I sat down with the Product Manager and got his opinion on commercial direction. It turned out he had a presentation, that had already been presented to other managers, with his idea of a roadmap. It was a well-thought through plan; it’s just that the dev team hadn’t yet seen it. That was another easy fix – I got the Product Manager to give the presentation to the developers and let them challenge the rationale. With this approved, he could then go away to create a 5-year roadmap – rather unusual at Redgate but vital for giving the developers a sense of confidence that the project wasn’t about to be stopped for another year again.

The outcome of the Product Manager’s work was that there were two obvious big features to be done soon – support for Active Directory and support for SQL Server Availability Groups. Both of these were features which competitors had implemented already, and were actively costing us sales. The work felt likely to take a few months, it was mid-April 2015 and there was a big tradeshow, SQL PASS 2015, coming up in October. The way forward seemed clear. I’d re-focus the whole team on those two features and temporarily shut down the other distractions the small team was simultaneously trying to work on (mainly support escalations and code quality improvements). Stopping distractions, and especially support escalations, isn’t easy, and can’t be a long-term solution, but in some cases I’ve found it to be a very useful tool. If you have the right conversations, even the support personnel in the firing line from customers can be brought into the idea.

Some people may question the idea of stopping the work to address code quality but the fact is that random pieces of improvement work were being picked up by developers with little planning or sense of what the most important work to do was. Instead, I asked the team to just write down the known technical debt on Post-Its as they were discovered, and stick them to the wall. Together with the actions from the fishbone retrospective, that became a visible reminder of how much debt needed paying back and, in due course, would form a backlog of improvement work to be addressed.

The tech debt wall

Of course, things never are straight-forward. Just as I was starting to get this running, a critical security vulnerability was found in SQL Monitor 4.1. The plan had to be put on hold while SQL Monitor 4.2 was released, and the fix was also backported to previous versions of SQL Monitor.

Explicitly showing what work is prioritised and what is to be done later on

 There – my job was done. The team had a road to follow and, a month or so after joining them, I could leave them in the hands of their normal Project Manager to continue the work…

Speeding up

At the end of July, I returned from a holiday to discover that the existing Project Manager had decided that he no longer felt confident in managing the project. It was a very brave decision to make, and meant that I was catapulted back into the SQL Monitor team again – this time as full-time Project Manager.

My job, though, was fairly obvious by now: keeping the team focused on delivering in time for SQL PASS 2015. This mainly consisted in keeping a fairly tight reign on the team’s approach to sprint planning and capacity planning, at least at first. This ensured also that there was no time available for some of the quality improvement work the team wanted to do, a deliberate choice by me to keep the sense of purpose. Over time, we found a way to handle support escalations once again, and I eventually released the brakes I’d artificially applied to guard against scope creep/changes.

To bring the team back on track, we enforced user stories, estimation and acceptance criteria.

We did it – SQL Monitor 5.0 was released just before the tradeshow, on time and without significant amounts of cutting things from the planned scope.

Through the work on version 5.0 we’d deliberately not released frequently: releasing was hard and required extensive manual testing because the automated tests were unreliable or covered the wrong things. Given the length of time since the last major release, and the team’s lack of knowledge, trying to release regularly could have caused too many derailments.

So, having reached SQL PASS 2015 intact, it was time to set the next challenge for the team: work out how to release frequently. For the major release, the testers had done an extensive risk-based analysis on the major areas of the product they’d need to test. They now used that as a first step to working out what minimal testing would be required. Meanwhile, the developers set to work getting rid of those unreliable automated tests, replacing them where possible, and changing our branching strategy so we’d always be in a position to release.

And that backlog of improvements to the code we needed to make? I got buy-in from the stakeholders so that we could keep our promise. We gave the team two months, without pressure to deliver features, to start working their way through the backlog.

By the start of 2016, we could release every sprint and some of the most egregious code problems were gone. The bike had gained its own momentum.

Providing the oil

Naturally, it hasn’t all been completely plain-sailing. The release notes from the start of 2016 show that there were several bugs and regressions that we introduced as we moved to the new model. For the customers who were affected, we’re sorry. But the fact that the SQL Monitor code, while still far from perfect, is improved, better understood by the team and able to be released quickly means that we’re in a much better position to do some great work in 2016 than we were last year.

By now it should be clear what my role in all this was. The team is pretty much unchanged. The way they work is only slightly different. The developers, testers and designers are still the gears, chain and wheels of the bike. Without them, we wouldn’t have a bike at all. My job was one of lubrication: providing the oil and a bit of direction and momentum to ensure they could go on their journey. It was done through adding brakes and stabilisers where necessary to prevent them from going too far off-course in the early days, then empowering the individuals by giving them the time and space to address the problems they wanted to fix and by protecting them from the mud of management that might have interfered with the way they were working.

Postscript

The team’s now working on some really exciting stuff ahead of SQL PASS 2016, including a very impressive new dashboard which is nearing completion.

As for myself, my mentor, Simon Cromarty once told me that the aim of any project manager should be to make themselves redundant: You succeed when the team doesn’t need you any more. So, in a rather perverse way, it should be good news that I stand to be made redundant from Redgate in the coming weeks. If you need someone to help oil your bicycle,  let me know…

What is technical debt?

This article is my own synthesis of ideas presented at Lean Agile Scotland in September 2014 by Dan North, Jabe Bloom and Torbjörn Gyllebring, with some of my own embellishments. Any misunderstanding of their points is mine! I’ve linked to their original talks at the foot of this post.

Conway’s Law says that the design of our system will be rooted in the design of our organisation.

So, we can never design a system from scratch: some of the design will have already started before we start designing.

This isn’t necessarily a problem, however: indeed, we should embrace it, because organisations suck if they don’t have the right APIs and other architectural borders in place between where teams are (that’s when teams start to get bureaucratic layers preventing their work from proceeding as their pace.) We should take time to get this right, and this is why having micro-services to do communication between teams is a good idea.

However much we work on this, however, we will face problems in the code we write, many of which will relate to the architecture. We can either chose to fix the symptom (via a quick fix) or to fix the underlying problem (which is generally more time-consuming). Quick fixes aren’t necessarily bad when applied in conjunction with a longer-term fix but remember they are akin to painkillers, and you can’t take painkillers indefinitely.

Quick fixes often take the form of a mandated structure: we might add too much or too little process, a particular build system, an architectural design ‘recommendation’, a decision on a particular source control system or IDE, or similar. As managers, we should be especially careful with such quick fixes. We are aiming to apply a ‘Goldilocks’ amount of constraint on our teams: too constrained and development will stop because the people can’t do their job; too little constraint and there will be too many options to do the right thing. The right amount is a strategy that’s clear enough to give us a task for today and a constrained set of options for the future. That strategy is actually a conversation – top-down constraints from management, and bottom-up information and designs from the development teams.

Partly because of the difficulty of identifying the ‘Goldilocks amount’ without information from the team (which presupposes time taken to do investigation), quick fixes generally tend to exhibit more unintended consequences than fixes that correct the underlying problem.

In a Cynefin sense, rather than taking time to analyse a problem as demanded by Complicated scenarios, our quick fix has made matters worse by creating a Complex relationship. The side effects can’t be foreseen, but become apparent in retrospect. Worse still, the quick fix may fail to address the root cause of the problem, and so we may get a positive feedback loop causing problems to increase as a result of our solutions.

This is technical debt, because the system starts constraining what we can do.

Cynefin tells us we should monitor for this positive feedback and, when we sense it, take time to respond to it, possibly by rolling back the change and trying a different approach.

To check for technical debt, therefore, we should periodically take time to ensure that our system isn’t constraining us. We can do this, for example, by ensuring our tools haven’t become our masters by checking that we can still build our products using a single command line (without complex CI systems) and that refactoring can be done in Notepad (without Resharper).

Original videos:

Understanding a feature through 3-amigos

The last project I ran here at Red Gate was on SQL Compare / Data Compare 11 project. SQL Compare is a superficially simple product designed, as it’s name suggests, to compare Microsoft SQL database schemas. Its cousin, SQL Data Compare compares the data in the tables.

Like the product itself, the Compare 11 project had a superficially simple goal: add support for the new features in SQL Server 2014. Easy, right? It turns out, not so much…

The largest new feature is Memory-Optimized Tables (MOTs): the ability to keep data in memory so you get significant performance improvements through reduced disk-access. But as you dig into what MOTs can and can’t do, you realise that you’ll need a lot of special-cases in the code to deal with the limitations. The details of those limitations is well outside the scope of this post, but one of my colleagues Michelle Taylor has written a useful post on our company blog for those who want to know more.

When the team came to start work on this story, which was before the release of SQL Server, some of the limitations weren’t immediately apparent. This led me (as project manager) to a false sense of security, and so I was far too lax on getting the user stories and acceptance criteria defined in detail. The lack of knowledge this created in the team caused the feature to become massively under-estimated: just 50 task-points (at their velocity, each task-point turned out to be just over an hour of real work).

The first tasks related to this story went on the Scrum board early in the project: ‘Add property to CreateOrAlterTable’, ‘Add property to DatabaseObjectsTable’, ‘Update DatabaseObjectsTable.Equals()’. You see what’s missing? We had dived straight into implementation with no form of planning first. That first sprint was estimated as 15 points. By the time we got to the end of it, we had uncovered quite how unexpectedly complex this feature was likely to become. We were nowhere near 30% (15 out of 50 points) complete on the feature. We carried some of the tasks forward to the following Sprint, however, trying to convince ourselves that we’d crack it soon. Before I knew it, we’d spent nearly a month on this feature, continually uncovering more and more complexity, and morale on the team was starting to become impacted.

Even then, my monthly project A3 report excessively optimistically promised that we’re complete both Inline Indexes (another 2014 feature) and Memory-Optimised Tables in the next four weeks.

It was time to pull the Andon cord.

Luckily, this also coincided with a slight change to business focus. The team was being asked to ship SQL Compare 10.7, giving support for connecting to SQL Server 2014 (but not the new features) to ship with the final release of SQL Server 2014.

Whilst this was a massive disruption to the team, it did give us some breathing space to find out more about MOTs before we had to work on them again.

By the time we were ready to start work on MOTs again, the Product Owner had defined the Acceptance Criteria in more detail. There were a series of tasks, themselves totalling 42 task-points in estimates, which centred on reviewing these ACs and making sure they made sense. This worked OK, and put us in a much better place, but with a large team, the meetings didn’t really work.

At this point, one of my colleagues pointed me to the idea of a 3-amigos meeting. I’d actually tried this once before on a different project, and I found myself wondering why I hadn’t tried this earlier on the MOTs work. The idea is to have three people (specifically the Product Owner, a Developer, and a Tester) in a room together, defining how the feature should work for users, in the code, and in test cases respectively. There’s a good write up of the meeting on the Scrum Alliance website; the only difference for us being that the Product Owner also doubled in the BA role for us. Although it felt slightly more waterfall than we were used to, the output from the meeting was a set of really well defined, clear Acceptance Criteria and a good common understanding of what MOTs involved, that was ready for sharing across the team.

The team re-estimated the work, and came up with an estimate of 250 points. In the end, it took 337 – still rather more than 250, but also far more than the original 50 points planned!

This process worked so well that we adopted the same meeting for other features in SQL Server 2014, rotating the role of the amigos through the dev team. As long as the communication about what was discussed is good immediately after the meeting, everyone became brought into the idea of 3-amigos, and ensured that the chaotic start to MOTs wasn’t repeated during the rest of the project.