High performing software engineering teams: how to grow them and how to slow them

16 min read Original article ↗

Mark Grebler

This article will take a close look at what makes high performing software development teams, as well as what hinders them. It will cover each level of the organisational hierarchy starting at individual software developer, then a team of engineers, full cross-functional product-engineering team, wider product-engineering department, and finish at the entire company. At each level, we will see multiple examples of teams to see what factors contribute to high performing software teams, as well as less well performing teams.

Here are some things you might get out of this article:

  • A way to identify high and low performing software engineering teams.
  • An understanding that although the task of building a high-performing software engineering team may seem like it is the responsibility of the people that make up that team, all other parts of the company can help or hinder the performance of that team. That is, you can have the highest performing software engineers in the world, but if they are constantly building the wrong thing, they may be next to useless.
  • An understanding of the types of things that help or hinder building high performing teams at every level of the organisation.
  • Some techniques for growing your high performing team (marked in bold).
  • A sense of frustration, since most of the secret sauce of how to build high performing teams is highly context sensitive and therefore there aren’t many one-size-fits-all solutions. In addition to the techniques described throughout the document, there is a final section which covers some general principles to apply at every level for how to do better.

Level 1: An individual developer

The most important ingredient for a high performing individual developer is a willingness (passion) to learn. Someone who is striving to master their craft. She has faith that there is always a better way to solve a problem and strives to uncover that better way. In doing so she learns more and becomes a better developer. By repeatedly doing this, she sees patterns that she has (or someone else has) already uncovered and solves problems more and more quickly. She seeks to master her tools. By doing this, an experienced or high-performing individual developer will move more quickly towards the goal of having a feature code-complete.

As a way to illustrate this, we can imagine the steps that a developer needs to take to get towards her goal of delivering a feature. The diagram below shows the path of an experienced developer, and how she takes small steps towards the goal more quickly than the inexperienced developer, who ends up taking a much longer path to reach the goal.

Experienced vs Inexperienced developer

Techniques for Instilling this desire for learning in engineers can differ from person to person. Generally, creating an environment where there is time to learn is a good place to start. It can be in the form of designated times, such as Google’s 20% time, or Hackathons. It could be by creating spaces for team members to share knowledge with other members, such as guilds (a community of members with shared interests across the organization who want to share knowledge, tools and practices) or Lunch and Learn sessions. It can best be achieved by ensuring that employees have some slack in their workday to try to learn new things. For example, by not constantly having tight deadlines. Carol Dweck has some useful ideas for instilling learning in people in her book Mindset.

A high performing developer also understands the “long game”. She understands that solving the problem is a small part of what is necessary, and that the real challenge is solving it in a way that will not slow her down in the future. That is, she tries to minimise the amount of technical debt she produces.

She strives to write readable and reusable code, usually by following principles such as SOLID. She uses processes and tooling that ensure that she can release code quickly and have confidence in the quality of her code by employing practices such as Test Driven Development, Continuous Integration and Continuous Deployment.

If we observe these two developers over a longer period of time, we can see how an experienced, high-performing developer continues to take steps towards each goal, and doesn’t slow down over time, whereas the less experienced developer has to take larger and larger detours as technical debt builds up.

Press enter or click to view image in full size

Tech debt slowing progress over time

Level 2: Team of engineers

At this level of the hierarchy, we observe a a team of engineers (Software Engineers, DevOps and Quality Assurance Engineers).

Misaligned team of engineers:

As we observe this particular team, we notice that they are fortunate enough to have a group of individuals who are all high performing by themselves, but in this team, they all appear to be pulling in different directions. The result is that the high performing individuals produce a team which is far from high performing. Their actual path is barely in the direction of their goal at all.

Misaligned team

This poor team suffers from a lack of alignment. The members of the team have assumptions about what their purpose is and what they should be developing, and these assumptions are not the same for everyone in the team.

Aligned team of engineers:

If the team members do work well together and have a clear understanding of the direction that they are going, then they can pull in the same direction. The team needs to communicate and collaborate to ensure they have a common understanding of each piece of work, and also about the overall objective of where they are going. As you can see, this better aligned team is moving towards their goal of completing the feature.

Aligned team

Techniques to achieve this alignment again differ based on the context of the team, organisation and the domain of the problem-space. Generally, the team should have some sort of identity, and long term vision which should provide high level alignment. Ideally the team members should have input into these in order to have better buy-in to their direction. For medium term alignment, most Agile software development methodologies try to achieve this by clearly articulating a goal for the team over the next period, or through their prioritised backlogs. Short term alignment is achieved by clearly communicating User Stories. The Product-Engineering level will cover this in more detail.

Aligned team of engineers who learn:

Alignment is one piece of the puzzle, but by itself is not enough to have a truly high performing team. It is possible to have a group of individuals who are well aligned and working fairly independently towards a common goal, but miss a key element of learning from each other. In the same way that a high performing individual needs to have a willingness to learn, members of a high performing team must have a willingness to learn from each other.

In order to achieve this, team members need to have psychological safety. They feel safe to take risks and be vulnerable in front of each other. As a result they learn more effectively from each other, and also have productive conflict to reach better conclusions. See Project Aristotle and The Five Dysfunctions of a Team

Techniques for building psychological safety and trust differ greatly from person to person and hence from team to team (how’s that frustration going?). To build trust, some teams do regular coffees or lunches, others go out for team activities, others play games. Meaning that without understanding the individual team and its motivations, simply trying to play some Trust Games may not be particularly effective. For psychological safety, a culture needs to be created where failure is embraced as an opportunity to learn.

This high performing team ends up in a state of symmathesy (learning together). When teams are doing this, their individuals are not just being productive (and producing individual output), they are generative. The generativity of an individual is the difference between the team’s output with that person and without that person.

If the culture of the organisation or team encourages individual productivity then some individuals may be productive at the expense of the team. In fact it is possible for productive individuals to have a net negative effect on the team. For example if the individual hoards knowledge or changes the codebase more quickly than other people can build up their understanding of it.

Generative people push for the team to grow together. They may sacrifice their individual productivity and may appear to be slow themselves, but do so in a way which significantly advances the team. A trait of high-performing teams is this generativity. See this article for more information. With this generativity, the team produces more than the sum of its individual contributors (dare I say it, synergy).

Symmathesy

Techniques for creating symmathesy revolve around encouraging and recognising certain behaviours and discouraging others. Environments where objectives or recognition focus on “Individual Contribution” or individual productivity will generally reduce symmathesy. Instead, set objectives and recognition around the team itself, and behaviours for that team such as collaboration and helping others. Shifting the focus to peer feedback rather than manager evaluation will help. Many of the Management 3.0 techniques can help.

Level 3: Product-Engineering Team

In some organisations, the engineers are an independent team, but in others, they are a sub-team that does not work in isolation but with another sub-team which includes product representatives (Product Manager, Product Owner, UX, etc). This Product-Engineering team is a full cross-functional team. And as we notice this team, their goal is no longer about producing code to deliver features, but customer value. Where do these features come from, and how do we know if they add value or not?

Some take the view that the role of the product team (sub-team) is to define which features to build and that the role of the engineers is to deliver those features; meaning that the responsibility is solely on the product team to determine what will add value. We’ll hover at this level and look at a few different examples of this and what actually works most effectively.

Really Bad Product Teams

Really Bad Product Teams (RBPTs) assume they know what features will add the most customer value. Instead of identifying problems or opportunities, and coming up with a solution to solve that problem, they define solutions in need of a problem. They define solutions without any thought for the possibility that they may be wrong, and that their solution may not solve any customer problem. They then scope a massive set of features that cannot be broken down, and the team delivers over a long period of time, thereby taking a long time to deliver something that completely misses the mark.

Really Bad Product Teams

Bad Product Teams

Bad Product Teams (BPTs) still largely work in solutions rather than problems, but will first prototype their solution (mock) as a way to test and refine it. But the prototype is often done without properly uncovering the problems and opportunities and as a result can only provide a minor course correction. From this point they are basically the same as RBPTs, except that their direction is slightly less far away from customer value because they have refined their solution.

Bad Product Teams

Bad Product Teams Doing Agile Badly

There is a variation on the BPTs, which is teams that deliver in an incremental or Agile way. Their method is similar to BPTs, but they break up the features into small increments instead of delivering them all at once. At first glance, this Agile delivery may appear to be a significant improvement. But the problem is, these teams do the incremental part of agile, but not the iterative. They deliver small increments, without revisiting what they have delivered previously to determine if they have actually added customer value. They never inspect and adapt, so they succeed in getting to the wrong solution, but with less risk than if they didn’t use Agile at all.

Bad Product Teams Doing Agile Badly

Good Product Teams

Good Product Teams (GPTs) understand that they get it wrong and that the solutions that they come up with may be incorrect. They clearly define a problem that they are trying to solve, or opportunity that they are trying to meet, and then test (feedback) and refine along the way. The teams deliver incrementally and iteratively and by constantly validating and refining, manage to reach their goal of delivering customer value.

From their well defined problem, they can produce measurable outcomes, and then each time they deliver, they can test if they have moved closer to the outcome they are trying to achieve.

Good Product Teams

Great Product-Engineering Teams

Truly great, or high performing, Product Teams, are not Product Teams at all, but rather part of full cross-functional teams including engineering. They work in a similar way to GPTs, except after defining the problem, instead of the product representatives coming up with the solution themselves, they involve their whole team (engineers, etc) in coming up with the solution. This not only results in a better solution, but also means the whole team has more buy-in and will get there faster (symmathesy at play again).

Great Product-Engineering Teams

To grow Great Product-Engineering teams, the initial focus of the team needs to be around clearly defining the problem, before defining a solution. The key activity here is to ensure you have an adequate Product Discovery process. Frameworks that can help with this shift the the focus of development away from long lists of features and towards learning loops that define a problem and measurable outcomes around that problem; building a solution; and then measuring to see if that outcome is achieved. For example Hypothesis Driven Development, Mobius Loop or Lean Canvas.

Level 4: Product-Engineering Department

It is clear that at this level, we are now past the the scope of an individual high performing team. It is still valuable to cover this level and beyond, because as we will soon see, a high performing Product-Engineering team can be ground to a halt if the rest of the company is not aligned.

The Product-Engineering department (which in some organisations may contain multiple different departments) contains all of the cross-functional software development teams in the company. Usually, each team has ownership of a particular product. Sometimes there are multiple teams working together in a Tribe, which has a common product. But all of these teams or tribes are contributing to a set of products which make up the product suite of the company.

Often each team is allowed to be self-organising, and will define its own direction. This freedom can be a double edged sword, and without proper oversight and alignment each product may pull in a separate direction which does not move towards the overall goal of the company. Products may compete against each other, or teams may be dependent on other teams which result in teams producing sub-optimal solutions to work around the competition or dependency. In both cases, the result is a set of product teams which are not aligned and as a result, the company’s products may not hit the overall goal of delivering value, no matter how high performing the individual teams are.

Misaligned Product Engineering Department

Level 5: The Entire Company

This level contains everyone in the company. We can take in each different department and observe how they move relative to one another. There are many parallels between this level and the previous ones. It doesn’t matter how high performing each department is, if the departments are not working together towards the same objective, then they will struggle to achieve the company’s goal. For example, sales may be incentivised in a way that makes them sell product features which do not yet exist and were never planned to be on the Product-Engineering team’s radar, jeopardising their objectives and delivery. HR may have a hiring and approval process which takes months, which means that other departments cannot plan and pivot quickly. Similarly for finance who may have an annual budget cycle whereas engineering may require staff changes based on quarterly planning. If there is no alignment between departments, they are unlikely to be pulling towards the company’s goal of delivering value.

Misaligned Company Strategy

Company strategy is a complex topic that is well beyond the scope of this document, but Richard Rumelt, in his book Good Strategy/Bad Strategy explains that a good strategy should contain:

  1. A diagnosis: of a key challenge, which identifies which aspects of the situation are critical.
  2. A guiding policy: for dealing with the challenge. An overall approach to overcoming or dealing with the obstacles identified in the diagnosis.
  3. Coherent actions: that carry out the guiding policy

Once a strategy has been well defined and well communicated, the culture needs to focus on aligning the business around that strategy by focusing on the company as a whole or Business Agility. For example Domains of Business Agility.

All Levels

As a final thought, there are some simple ideas (that can often be hard to do) to apply at all levels of the organisation to help grow high performing teams:

  1. A clear and well communicated company strategy that provides meaningful direction to all levels of the business
  2. Communication and collaboration at every level:
    We have seen the value that can occur when people act in a generative way by contributing more than just their individual output. This requires that every level needs to work together to learn effectively from each other and come up with better solutions. Different departments, different teams and different individuals all need to work together to achieve this at a company level.
  3. Transparency:
    In addition to creating trust, transparency and open communication also allow departments, teams, or individuals to know and understand the objective of others which is needed to ensure that alignment is occurring at every level.
  4. Empathy:
    Each department, team and individual needs to empathise with others to properly understand what they are trying to achieve and push the company towards its goal.

Conclusion

We have seem examples of what makes high performing and not-so-high performing teams at each level, as well as some techniques for growing high performing teams at those levels. As a reader you have probably been frustrated that most of the techniques start with “it depends” and end with “change your company culture to encourage learning, collaboration, understanding problems, measuring outcomes, and alignment”. Although you have not received a step-by-step guide for growing high performing teams, you should at least have a better understanding of what a high performing team and company look like, what makes them high performing, some ideas for how to grow your team, and an understanding that the entire company has a role to play in growing (or inhibiting the growth of) high performing software teams.