Building 10x software teams

Twice in my career I’ve had a boss mention, in relation to the team I was leading at the time, “I’ve never seen such a productive team before.” Sometimes it’s harder to see from the inside, but with the benefit of hindsight, in these cases, something special happened. It certainly isn’t something I can force to happen, and it isn’t from anything like pulling crazy overtime or just ‘working harder’. It’s more like an emergent behavior of the correct team members, the working environment and the problem that needs solving. Having done it twice now to a degree that people actively remarked on it, I think I’m starting to see the patterns of what is needed. When it happens, it’s a magical state of flow that the whole development process enters, and anything I can do to help you experience the same is time well spent on both our parts.

A lot of noise is made about 10x individual contributors. Yes, these can exist, but on their own (at least from my experience) their impact is more like a scalpel than an axe. I think there is much more to gain by focusing on team productivity, and I also think achieving 10x teams is worth basically any investment (or restructure) necessary to achieve them. This might mean more budget for some things, stepping on toes, pulling people out of the team to let them get their work done, maybe even firing people. But, if your software was written 10x as fast with the same size team, wouldn’t that be worth it?

Note, 10x teams aren’t teams that write 10x the lines of code, or that pull out a demo over a weekend (but then spend 6 months getting it to stop crashing), or that ship some software in record time but the software doesn’t solve a business need. These are teams that, over a period of many months, getting to years, consistently produce exactly what it is that the company needs, in a way that imposes minimal negative impact on other aspects of the company, while providing solid value. Often, in fact, the lines of code will be less. After all, more lines of code for the same feature really just implies more maintenance burden, and requiring maintenance stops the team from delivering new features.

Some things are game changers. Other things are just removing the death-by-1000-cuts productivity killers. And it’s a bit like any optimization problem - once you get the big issues, the things that used to be small issues are now big issues. If you want all 10-x productivity, though, it probably means that structural changes will need to happen. This will be uncomfortable. It probably won’t be the way things are done already. Which, if you think about it, is kind of the point, right?

A lot like plants, teams need to be nurtured. They need all the right ingredients - the soil pH, sunlight, water, nutrients… and too much of any can also kill them. So, what are the things that teams need, and what weedteamkillers should be avoided at all costs? Read on.

Things teams need

The technical side

  • Get rid of constraints that are holding the team back. If the team spends time waiting on QA, for example, that should be brought into the team and the team should be responsible for making sure they don’t break anything, themselves. Any time there is a handover of responsibilities, it probably introduces something in the order of a 2x slowdown. Yes, fixing this is hard. Greenfield development can make this easier.
  • Be careful of rewrites of components which are too large all at the same time. Rewriting smaller chunks is way faster and more effective. Don’t bite off more than you can chew.
  • A balanced test suite which can catch a large portion of the mistakes that are made.
    • Think of the test-suite as the one-way ratchet which stops you from slipping backwards by mistake.
    • The keyword is ‘balanced’. Any external interfaces need tests, because there are hidden external dependencies that will depend on the exact behavior implemented. Tests for hidden internal behavior are less useful in the long run, although they can be useful at implementation time.
  • Making sure each component is really solid before building on top of it. Tons of time is wasted whenever you have to go back and debug things on the level that you aren’t currently working. You don’t want to have to go digging for CPU bugs when you’re writing web pages, and while that’s an extreme example, it makes the point.
    • This means characterizing it deeply and making sure all the footguns are safely stowed away for future users (ie. us in 3 months time)
  • Explicit over implicit. Even if your code is a bit verbose, it will waste less time from retyping things than it would from people misunderstanding how it works. This also typically makes it more composable for future unforeseen use-cases, since it makes less assumptions about how it will be used.
  • Using conservative dependency choices. Battle-tested means it will get out of the way and you can focus on the actual problem at hand.

The organizational side

  • Clear long-term goals, for at least 6-12 months. A vision of what things would be nice to have in 5 years is also helpful. 5 years isn’t strictly required, but anything up to that is definitely helpful.
  • Let the team figure out how to achieve these goals on their own. As the expression goes, “Hire smart people and then let them tell you what to do.”
  • Constructive, timely feedback on what worked well and what didn’t. Agile (with a capital A) calls these ‘retrospectives’.
  • Be careful of making too detailed a plan: this can lead both to overconfidence in the planning, and inflexibility in execution. Inevitably some aspect of the plan won’t account for an inconvenient part of reality, and this needs to be expected. “The map is not the terrain.”
  • Somebody should be doing the front-running, trying to figure out where problems will happen before they do. This person should have the power to direct resources to prevent issues from arising - “a stitch in time saves nine”.
  • Lots of flow time. One way this has worked was scheduling all meetings for before 10am or after 4pm. Yes, all meetings. The other way was when everybody was working remotely during COVID, and online meeting culture hadn’t established itself yet. Amazingly, giving people time to do their work without distractions makes them more productive…

The human side

  • A strong focus on ‘impact’ - how much what you do helps to give the company value, long or short term.
  • Encouraging people to take initiative. Often this starts small and needs to be nurtured.
  • Hiring people with diverse skill-sets - someone from game engine design will spot different issues than someone who wrote machine learning systems. Even just different universities will have different curricula. Having everybody from the same university, or even worse the same lab at the same university, will mean that you don’t have the breadth of knowledge to even identify a whole host of problems, or the skill-set to solve them effectively once they become unignorable.
  • Making sure everybody has potential to contribute as they feel they can best. Different skill-sets in the team should drive the decision for which features, technologies and architectures are prioritized and chosen. Because skilled people are so rare, the detailed roadmap and execution plan should depend on the capabilities of the team, rather than trying to shoehorn the people you have into a predefined idea of what needs to be done.
  • Closely related to the above: people need recognition for the creativity and perseverance they put in. Lack of recognition will rapidly lead to disillusionment and burnout.
  • Various “agile rituals” are sometimes used to achieve the above points. Demos of completed features during sprint retrospectives, presentation by the ambitious junior to the rest of the team, ‘kudos’ channels in the company chat, bringing up recognition of team members during the team retrospectives. However it’s important that the reason for performing these rituals is to help the people execute, grow and be acknowledged, not to complete some checkbox in an Agile worksheet.

Things that kill teams

  • Internal competition between team members for recognition, advancement or anything else which is seen as being in scarce supply.
  • Treating team members as interchangeable units instead of distinct human beings.
  • Discouraging teamwork or other collaboration between team members.
  • Managers (or other teams) taking credit for things the team did of their own volition.
  • Micromanagement. If the team isn’t in charge of their own destiny, they won’t take the initiative to fix the things that slow them down.
  • Not having transparent mechanisms for career advancement, including interpersonal coaching, management coaching, technical coaching, and identification of missing skill-sets.
  • Firing a team member - a rule of thumb is that 2 people will resign for every 1 you fire.
    • An exception: toxic team members that the rest of the team don’t like or feel aren’t pulling their weight. These people should be moved out of the team ASAP to avoid collateral damage.

If you do all of this, you maybe have 50/50 chance of getting your 10x team. There’s some other magic as well, sometimes it’s there, sometimes not. But there’s also just a bunch of dumb organizational stuff which you should really sort out anyways, to let your teams stretch their wings and see if they really can fly. Worst case scenario, you fix all your organizational problems and they’re only 2x or 5x as productive. What a disaster.