Software Is a Team Sport

I’ve been overjoyed watching the Western Conference Finals this past week. I know. Some of you reading this don’t go in for “sportsball” talk, but if you bear with me (or skip ahead a few paragraphs) I promise I have a point.

The Thunder and the Spurs are two extremely elite basketball teams. Not only are both great on offense, they are both exceptional defenses capable of stifling a great offense. So elite and well matched that they pushed each other to the 7th game of a 7 game series, one that began with game 1 going to overtime.

But what I love to see is these two teams’ connectedness. The Spurs and Thunder are both high octane offenses designed to bend defenses past their breaking point: screens, rolls, counters, the kind of constant motion that creates a mismatch and puts a defense in what NBA players call “the blender.” And yet somehow, on both sides, there’s a defender already at the spot where the next pass is going. Someone has rotated off their assignment to be where the next problem will be, right before the problem gets there. It’s not 5 players all defending well, it’s a single, cohesive team. Steve Nash refers to this as “five fingers make a fist.”

You can’t draw that on a whiteboard. You can draw the scheme, and the scheme matters. But the scheme is necessary, not sufficient. At playoff intensity, against opponents this good, the only thing that produces those rotations is players who have spent enough time together to anticipate each other. They know their own assignment, their teammate’s assignment, who’s a step slow, who can recover, who’s about to need help, and who’s about to give it.

And that brings me to my point about software

The team is the discipline

Last week I wrote about good architecture being a discipline: the work of choosing the harder, right path again and again instead of the easier, wrong one.

The thing I didn’t say last week is that discipline isn’t an individual property. It’s a team property. A codebase reflects the discipline of its least disciplined contributor, not its most. You’re only as good as your worst engineer.

I mentioned last week a codebase I worked on whose architecture was genuinely great. Clean separation of concerns, easy to test, easy to add to. When they needed to scale up the team for a big summer push, they brought in additional engineers from outside our core team. Most of them integrated well. Senior engineers tend to feel out the shape of a system quickly. Like a veteran basketball player on a new team: the exact plays are new, but the fundamentals are familiar.

But not everyone we brought on operated that way. At least one had what I’d describe as a “this PR does what was asked” attitude. The change worked. The tests passed. By the narrow definition of the ticket, it was done.

The friction was everywhere else. It didn’t fit the architecture. It didn’t anticipate where the next change would land. Explaining why we were requesting more iterations started to feel like a job in itself, and the temptation to just merge the PR and quietly rewrite it later was real. It would have been faster in the short term.

The long term is where this shows. Even after that engineer rolled off, the rough edges they left behind didn’t roll off with them. The architecture remained great in the abstract, but the discipline that maintained it had been broken in a small way that left us cleaning up edges after the big push.

We need an orchestra

Here’s how a senior engineering leader I worked with put it once: “I hear a lot about rockstar programmers. That’s great, but we need an orchestra. If one person is soloing and the rest are just watching, we have a mess, not a win.”

He was right. Great engineers are a joy on your team and the gap between great and replacement level is real. But just like basketball, software is a team sport.

Even the best player in basketball can’t do it alone. Look at Victor Wembanyama (Wemby). He’s 7’6″, arguably the best defensive player ever, and a credible offensive threat at every level. But even he didn’t make the playoffs his rookie year. He needed a team.

Engineering teams work the same way. The strongest individual contributor isn’t valuable just for what they ship. They’re valuable for what they enable other engineers to ship. The senior engineer who handles the gnarly integration work creates space for the rest of the team to focus on what they can own. The architect who insists on clear interfaces gives everyone else the seams they need to work in parallel.

Great engineers are great teammates

Sometimes the best work doesn’t show up in any commit history. Great engineers invest in the people around them, not because they’re nice (though many are), but because they understand that the team’s discipline is the work. The architecture they care about doesn’t get maintained any other way.

Same with basketball. There’s been shot after shot of Wemby with an arm around a teammate or a coach, talking through something specific. Even at his level, even with his physical gifts, the work of making other players better is something he’s choosing to do.

This compounds. It compounds in the codebase, because the team’s collective sense of what good looks like keeps rising. And it compounds in the team, because everyone gets better when surrounded by people who are actively trying to lift them.

The point

A great architecture is necessary. Great individual contributors too. Neither one is enough on its own. In isolation, each is necessary, not sufficient.

What makes software work is the team that actually carries the scheme: a group of people who know each other well enough to anticipate each other’s work, who play the roles only they can play, and who invest in each other’s growth.

You Might Also Like…

Developers Are Human

Over 30 years ago, a CS professor of mine dropped a piece of wisdom as an aside in class. Dr. Soroka told us that every time he fixed something in a program, he got a little jolt of happiness. A little high. And he’d noticed something curious: the size of the high was not proportional […]