Craft a high performance team? 8 straightforward (proven) tips!

Were you ever in the position to be lucky enough to be in a team that could, quote unquote, just get shit done? Where in every sprint you could move mountains, and burn those agile stories in seconds?

I was fortunate enough to have been part of such teams throughout my career, although they were the exception rather than the rule.

How did I know those were super teams?

In part it’s just a gut feeling. Sometimes, you just *know*, right?

However, I came to realize that there are some ways of working that seem to be shared across all of these teams. Call those the ingredients, or ways of cooking up software, that make those teams highly effective.

In this article, I’ll share some observations about things that I have seen as a developer, that really worked well in increasing the performance of a team.

I’ve narrowed it down to 8 concrete tips you can try out yourself. With any luck they will supercharge your team too! Have a good read, or scroll all the way down for a video of my talk about these super teams on J-Fall.

1. Story refinement

We used to do story refinement like this:

  • Do a three amigo’s session with business, PO and one developer
  • Write the story and refine with the team
  • Drop it on the backlog
  • Start working on it after a few weeks

…and then, of course, we would barely remember the intricate details of the story, or why we wrote it in the first place.

So we started doing something we call Just-In-Time Team Kickoffs.

It takes the good bits of story refinement and solves some of the problems we had in the old way of working:

  • The whole team is involved. That means everyone, not just a product owner, business analyst and maybe a developer.
  • Timeframe is timeboxed. If we can’t finish, we’ll stop and plan a new one the next (working) day.
  • After the story is clear, the team creates a design on the spot. That can be a class diagram, sequence diagram, or just some lines of text explaining implementation details.

Now, after we’re done, we start working on the story immediately. That way, the context and details are still fresh in everyone’s mind.

If possible, we all work on the same story. That’s not always possible with small stories, but we strive to do it as much as possible nonetheless.

Enjoy an example below. From a story, we make a design, everyone comes up with subtasks to perform, and then we’ll immediately start to work on it.

Tip #1: Do Just-In-Time team kickoffs for mutual context and understanding.

2. The product owner

Our product owner is a busy guy. He’s always in meetings, so what now, that one of the details of our user story has changed and we don’t know how to approach it? Should we just sit and wait around for the product owner to magically re-appear?

Of course not. The team has to able to move forward, always.

The way we improved that is to spread the product owner’s knowledge across more individuals, like a ‘backup’ PO or business analyst. That way, someone is always available to answer questions.

Tip #2: Make sure the Product Owner, or a backup, is always available.

3. Team roles

We all want to work on the same story. But our team consists of frontend developers and backend developers. Quite often, there is no backend or frontend work  at a certain point in a story. Worse, sometimes there is no frontend work for weeks. Should the frontend developer sit idle during that time?

We tried looking for a Full Stack Developer, but we found out those don’t exist. Prove me wrong and you’re hired. The IT landscape is huge and so complex it’s virtually impossible to find someone who knows everything about everything.

So what we did was moving developers out of their comfort zone and encouraged them to pick up work they’re not naturally inclined to do. We do this through mentorship:

  • For a frontend task, we put a backend developer in the driver’s seat with a frontend developer pairing with him as a mentor.
  • For a backend task, we put a frontend developer in the driver’s seat with a backend developer pairing with him as a mentor.

Now, developers have to be open minded about trying something like this, of course. But if it works the developers will move closer together and be able to pick up arbitrary tasks from the Scrum board.

They will become T-shaped: they still have a core competence, but are comfortable picking up other tasks.

Please do not have the illusion that you will end up with all devs capable of trading places. But they will be able to cover for each other, especially in case of calamities, absence, etcetera.

Tip #3: Pair different disciplines to grow T-shaped developers.

4. Build pipelines

All is going along well in your build. You don’t break a sweat even waiting for an hour of performance testing. Until you get to the dreaded UI test. It’s always broken or unstable, and fails after 20 minutes. Sounds familiar?

In order to move along fast, your pipelines have to be quick to be able to quickly fix issues.

  • Minimize your performance test. During the day, you only need to test if something is seriously broken, performance-wise. You can find out about that in 15 minutes or less. Only run a full performance test nightly.
  • Minimize your UI test so you only need to test things that cannot be tested in any other way, like unit tests and IT tests. For frontend, Jest and container testing will do.
  • And most importantly: maintaining a UI test is normally a shared responsibility across teams. Make sure everyone feels responsible for it, because it’s everyone’s job to bring stuff to production.

Tip #4: Keep your pipelines Fast and Stable by eliminating unneeded jobs and minimizing flakiness.

5. Code reviews

We used to be a team that did ‘code reviews by pull requests.’ Someone would push a branch and then ask someone else to review it.

We found this to be not effective, since only the submitter and the reviewer know intimately about this piece of code.

So we started doing Team code reviews.

How to properly give a code review

Remember how we all work on the same story? After everyone’s done implementing, we do a meeting with the whole team to review all changes:

  • The developer that has finished a certain subtask presents it to the rest of the team, explaining how it works and what decisions were made.
  • The team then comments on the changes. These can be everything: about naming, structure, possible bugs, you name it.
  • All subtasks are reviewed in this way.
  • The team writes down all findings and puts them as extra subtasks on the board for that same story.
  • The story will not move along the board until all review tasks have been completed.

This way, the whole team knows about the details of the code and why some decisions were made. The next time that code needs to be touched, every team member knows about it, so there is no need anymore to say ‘Please give this to X, he worked on this previously and knows how it works’.

Tip #5: Do joined team code reviews for every story so the whole team knows about the code.

6. Technical debt

If you don’t resolve technical debt immediately, it will slow you down to a point that nearly every change will take forever. And I do say nearly here, because you won’t come to a full stop, you will just be moving along very slowly.

That’s called a quagmire and it is even more dangerous than stopping you in your tracks, because it’s not always immediately clear you’re in trouble.

We used to solve that by putting tech debt on the backlog:

The problem with this approach is that you don’t know what technical debt exactly holds you back from completing a story in a fast and concise way. It also gave us an excuse to just ‘park’ tech debt somewhere and let it be the product owner’s problem.

The only way forward is to make sure you don’t have any technical debt to begin with.


Sounds impossible? It is. But you can severely minimize it by adhering to the following:

  • Keep issues reported by automated tools like Sonar, Security Scan, etc. at zero at all times. If there is an issue, solve it. If there’s a false positive, flag it with a comment so it won’t show up again.
  • Code-smells and other technical debt that can’t be detected automatically should be detected during team code reviews, and put up as subtasks on the story at hand. We already talked about this.

Tip #6: Keep technical debt at zero, or at least at a bare minimum, at all times.

7. The Scrum Coach

“From now on, I will manage your scrum needs! Why don’t you do planning poker?”

“Eh… because we don’t need to. Everybody on the team has been in the team long enough and we’re pretty predictable at this point.”

“Yeah but how long does something take? Ehr… what about velocity? We can compare it with other teams!”

“Ehr… no… you can’t.”

Bottom line here, keep an open mind, but don’t mindlessly adopt rituals just because they’re in the book. Keep what works for you and jettison all other stuff.

Tip #7:  Be sensible and cherry-pick what rituals work for you.

8. Team composition and dynamics

This is probably the hardest to get right, because it involves people and it is not an exact science. But you’ll probably recognize the following:

  • When you have a team with only junior developers, you will get nothing done because they don’t know how to solve things.
  • When you have a team with only senior developers, you will get nothing done because they will argue constantly about how to solve things.

So it’s pretty obvious you need a healthy mix here.

Also, not everyone is the same. People tend to fit themselves into primary or secondary roles in a team, depending on their natural characteristics. Now, there are numerous methods like Belbin that will help you in finding out characteristics and what you’re missing in a team.

I can give you an example of our team:

Here are some of the roles we encountered:

  • The coordinator. Leads from the front and pulls the team forward.
  • The plant. Just sits there and thinks stuff up. Essential for innovation.
  • The implementer. Team worker who just want to get stuff done (I’d like to think that’s me, however, opinions might differ).
  • The researcher. Kind of like the Plant, but gets his information from his corporate network.
  • The perfectionist. Never skips the details.
  • The investigator. Learns from other teams and brings back the knowledge.
  • The team worker. Essential to make the team work together. Good at pairing and mentoring.

Having a good mix inside your team is vital.

Tip #8: Have a good mix of personalities and experience in your team.

To summarize

That’s it! 8 simple tips to bring your team closer to optimal performance:

  1. Do team kickoffs for mutual context and understanding.
  2. Make sure the Product Owner, or a backup, is always available.
  3. Pair different disciplines to grow T-shaped developers.
  4. Keep your pipelines Fast and Stable by eliminating unneeded jobs and minimizing flakiness.
  5. Do team code reviews for every story so the whole team knows about the code.
  6. Keep technical debt at zero, or at least at bare minimum, at all times.
  7. Be sensible and cherry-pick what rituals work for you.
  8. Have a good mix of personalities and experience in your team.

Sure, some tips might work for you, some might not, but experimenting is key here. Good luck! I am really curious to hear how your team has managed to improve its performance!


Here is my talk about what makes super teams tick on J-Fall:

Leave a Reply

Your email address will not be published. Required fields are marked *