As a team lead I have started to become more interested in how to build high performing dev teams than in building the actual software itself.

Don’t get me wrong, I still love building software.

But when you become responsible for building and maintaining the system of humans whose output is high quality software systems, you find that focusing on the team can be a much higher leverage activity.

If you do it poorly, you create a disjointed, inefficient team with a lot of friction. The output is buggy code and a very expensive black hole for company money.

If you do it well, you create a delightful working environment that seemingly effortlessly produces a continuous stream of beautiful, working code that whisks away knotty business problems like a magic software wand.

So what makes the difference between a happy, high performing1 team and a miserable, low performing one?

And how can a team that consists of individually brilliant performers still fail to produce quality code that solves real business problems?

How do you even know if your dev team is high performance or not?

I’ve put a lot of time and thought into these questions.

Having worked the coalface as a frontline developer for years, I have seen a lot of what doesn’t work.

That’s led me to form some fairly strong opinions about what does work.

The answer isn’t immediately obvious (software development productivity is notoriously hard to measure).

In fact, if you’re a non-techie reading this you may have absolutely no idea if your dev team is below average, average, above average or spectacular.

They say they’re doing well. Can you believe them?

Today I will attempt to demystify the situation by outlining five fairly reliable and unfakeable indicators that a dev team is performing well.

1. Consistent rapidity of development

High performing development teams ship new features rapidly consistently over a long period of time.

This metric needs to be very clearly defined, because even poorly managed teams can occasionally ship new features rapidly for short periods of time by sacrificing code quality and forcing devs to work longer hours.

This is only a worthwhile tradeoff when there are hard deadlines involved2 and the timeline is relatively short (on the order of weeks).

When pushing the red line like this, the piper must eventually be paid. After the line is crossed, output will slow to a crawl and there will be a surge in bugs.

This is the time to stop, and take a week or two to regroup and get code quality under control again.

This particular tradeoff is usually pushed too far by bad managers who don’t understand the nature of software development and treat software developers like recalcitrant children who require arbitrary deadlines and harsh whippings to get the best out of them.

Nothing could be further from the truth.

Good quality developers do not require any external pressure to get work done. They are creative and intelligent individuals who take pride in the quality of their delivered work and are constantly pushing themselves to improve.

In fact, if you try to apply external pressure through too much structure, clearly arbitrary deadlines or quantitative output measurements (KPIs) you will often see a decline in performance as developers interpret this as a lack of trust and a failure by management to recognise that they care deeply and intrinsically about their work.

Did Picasso need KPIs?

Well managed teams are self-motivated to maintain a good, balanced pace with natural downtime and time for refactoring built into the cycle, leading to a consistent and rapid delivery tempo.

One thing to bear in mind is that if the product process itself is broken, measuring shipped features may not be a good indicator because the team might be solving the wrong problems.

So, the real best metric to optimise for is:

“How many business problems is the team solving each quarter”

2. Low bug count

High performing software development teams ship code with few bugs.

You’ll hear a lot of arguments from people claiming this is not true. You might hear such excuses as:

  • We work on a legacy codebase so it’s inevitable that things will break
  • We are deliberately sacrificing quality to ship code faster
  • We’re making big changes so there will invariably be problems
  • These bugs are due to X third party system/integration
  • That’s just how it is when you develop in Y language

These are all, to put it politely, baloney.

All of these problems can be dealt with in a way that reduces the number of shipped bugs to a trickle.

There are well established methods and techniques for dealing with legacy codebases.

If quality is being dropped to ship code faster, you’re setting your future self up for a major headache - drop scope instead.

Big changes require big testing.

Third party bugs can always be worked around - see Erlang’s process model for an example of how this can be dealt with spectacularly well.

And lastly, if your choice of language is contributing to the bug count, find a different language that’s better suited to the task (e.g. dropping JavaScript for TypeScript, ReasonML or Elm).

A large number of bugs is indicative of a failing somewhere in the process. Good dev teams will find ways to monitor shipped bugs and come up with creative technical solutions or a change in process to ensure that it stays low.

A high rate of shipped bugs is inexcusable.

3. Very little process

High performing development teams do not require very much process.

An overbearing process is all too often an attempt to compensate for poor-mediocre developer talent. It never works.

Top down command & control style management works well for controlling output quality when dealing with thousands of unskilled factory workers, each of whom does a tiny but very well defined job.

Software development is not like this.

Anyone who treats software developers as fungible and tries to compare the software development process to an assembly line is demonstrating a tragic misunderstanding of how software actually gets built.

The important thing to understand is that software development is not actually about building things, or even about coding. It’s mostly about getting to clear thinking.

The code itself is just a byproduct of the completed clear thought.

Thinking about code is creative work in the same way that painting a picture is creative work.

You could certainly get a guaranteed number of brush strokes each day by applying a stifling process and rules to a team of grunts pulled off the street, but the finished painting will most likely be a worthless mess.

Good developers react poorly to the imposition of too much process for the same reason that they react poorly to artificial deadlines - because it belies a lack of trust in their work.

It demonstrates a failure to recognise that they are already self-motivated to produce the best work possible anyway.

Having said that, some process is required. Personally I like to apply MVP (minimum viable process) and aggressively strip process away where possible, as it has a tendency to ossify and grow like a cancer if you let it.

What little process there is should complement the team, not detract from it.

Examples of good process:

  • Mandatory code reviews
  • Some sort of weekly/biweekly retrospective meeting
  • Daily standup (when used to discuss tasks)

Examples of bad process:

  • Waterfall, scrum or anything else of that nature that places too much reliance on up-front estimations
  • Mandatory test coverage requirements
  • Daily standup (when used as a sort of micromanagement session where each dev feels they have to justify what they did yesterday and what they are going to do today)

With happy and highly skilled devs, less process generally translates into higher velocity and a more flexible team.

Business requirements change frequently and a lightweight process allows your dev team to be able to turn on a dime to meet them.

4. Developer happiness

This one sounds trite but in my experience it is anything but.

A very naiive managerial school of thought might run like this:

“If people are happy it must be because they have plenty of free time to be happy. We don’t want people to have free time and be happy, we want them to work!”

This sounds so obviously wrong that it may be hard to imagine that anybody really believes it, but I can assure you I have known workplaces where it’s basically assumed that if you’re happy, you can’t be working hard enough.

This attitude does not get very good results in software development.

As stated above, software development at the highest level is deeply creative work.

It is also deeply rewarding work.

Developers are most happy when they feel productive, when they feel like they are working on something important and when they are given the time and resources necessary to do a good job.

For this reason, developer happiness is one of the best indicators of overall productivity.

The most common cause of unhappiness in good developers is a hostile workplace enviroment that is preventing them from doing the work they want to do in the way they know it should be done.

This hostility can take the form of top down pressure e.g. to ship features without regard for overwhelming technical debt (generally encouraged by non-technical managers who don’t understand what they are doing) or external factors such as loud ambient noise or constant interruptions.

It can even be down to something as simple and embarrassingly cheap to fix as an inadequately powerful computer.

If you’ve hired the right people, the work the developers want to do is the work that’s most beneficial for the company.

So it pays to remove obstacles and let them get on with it.

5. Beauty of delivered software

The final indicator of high performing teams is that the produced software is beautiful.

A classic example is Stripe’s famously elegant and beautiful product web pages3.

They simply ooze quality, and you can’t have that kind of quality without it permeating throughout the entire company.

In short, on a subconscious level you know you can trust the quality of Stripe’s backend product because of the unfakeable quality of their customer-facing web pages.

In the same way for your team, the finished product should look beautiful to your users, but the code on the inside should also be just as beautiful even though no customer will ever see it4.

This philosophy is not about impressing other people. It’s about holding yourself accountable for the quality of your work.

It’s about taking pride in your work as a craftsman.

When your product lacks quality on the inside, this sloppiness has an uncanny ability to leak through to the outside experience. Things just won’t look or work quite right.

A team where developers, product and design are all talented and jelling well5 will tend to produce software that is beautiful both on the inside and the outside.

If your product is not beautiful someplace, regardless whether anyone will ever see it, your team is missing something, and this will make its way to the surface in the finished product.

Concluding remarks

The smart, perceptive reader may have noticed that a most of the points above are about being somewhat “hands off”.

That’s because the only way to get a high performing dev team is to hire high-performing people and trust them with a lot of autonomy.

This requires a large degree of trust.

You cannot apply top-down control to mediocre people and expect excellence.

The only way to achieve excellence is to hire great people and give them a lightweight process and the freedom to do things like undertake lengthy refactors, or choose an appropriate tech stack.

If you do this, you’ll find that excellence and happiness are the natural outcome.

So, to recap, the five key metrics are:

  1. Consistent rapidity of development
  2. Low bug count
  3. Very little process
  4. Happy developers
  5. Delivered software is consistently beautiful

If you have all of these, then congratulations, you have a high performing dev team!

If you’re missing one of more of these, something is not right with your team. Either you hired mediocre/poor talent, or some external factor is preventing your team from working effectively.

Either way, as a team leader it’s your job to fix it.

Thanks to Chris Gregori, Marcel Cutts, and Deividas Karžinauskas for reading drafts of this.

1. An interesting point to note is that you almost never see a happy, low performing dev team or vice-versa. Developer happiness is usually an excellent weathervane for developer productivity.

2. Contrary to popular belief, most deadlines are actually soft deadlines, not hard ones. You can find out if a deadline is hard or soft by asking a very simple question: “will it torpedo the company if we miss this deadline?” If the answer is no, it’s not a hard deadline and killing your team to meet it will be unproductive in the medium-long term.

3. About product design, Stripe says “we think that building an internet business is a problem rooted in code and design, not finance.”

4. In the Apple II, even the circuit boards were designed in such a way as to be beautiful.

5. For more on the importance of “team gel” I recommend reading Peopleware.