Great Eng Teams - Praful

7 min read Original article ↗

I've worked on a lot of software engineering teams over the years, both at massive companies and zero-to-one startups. Some of those teams have been great, and others not so much.

"Great" is a vague and loaded word, so as a more precise definition, I think great engineering teams do two things. First, they have an incredibly (almost magically) high output, productivity, and quality of product shipped, adjusted per engineer. Second, is that they bring out the absolute best in the people on the team. In my experience, great teams tend to be more professionally fulfilling, and also just more fun to be a part of.

In this way great engineering teams are not too different from great sports teams[1]: both are environments where everyone plays their best AND end up winning the game. The current team I'm on definitely falls into this category. When I tell people our team size[2], they are confused, if not skeptical, especially since we've been shipping like this before the wave of AI coding.

I reflected on this, and on other engineering teams I've been a part of, and found some hopefully not-super-obvious insights into what lets teams, and therefore the people within the teams, really shine.

The TLDR is: I think there are 5 characteristics that separate great engineering teams from those that are less great:

  1. High trust over process
  2. The builder decides
  3. Almost too ruthless prioritization
  4. Hiring player/coaches
  5. Hard work as a default

High trust over process

Any great team trusts each other immensely. As builders, we need to ship things that work well and don't break. One way to do this is to have extremely structured and strict processes, which can grind velocity to a halt. Another way is to trust your teammates at the level that soldiers trust each other with loaded weapons.

You need to trust that your teammates sincerely care about the quality of their work. That they won't ship a bug on a Friday night and then disappear for the weekend. That they will step up and make tough decisions when they need to, but not overpower you when it's your turn to lead. That when you make a mistake they will offer a helping hand. That if they are making a prod DB config change, they have thought about it carefully, and shared appropriate context with the team.

Not to say that all process is bad, but process needs to be thoughtfully added, especially if it's being used as a substitute for trust.

A high trust environment can be scary, but it empowers individuals and brings out their best, rather than settling for the lowest common denominator. It lets people take risks that allow for uncapped upside and lets teams stay small and agile.

I would much rather hire for trust over "experience" or "skills". To keep the sports analogy going: hire someone you're excited to pass the ball to.

The builder decides

This philosophy can be boiled down to: the person doing the work is the one to make the decision. Teams can save thousands of hours of meetings and analysis paralysis with this simple rule.

If you're working on something: you are the default decision maker. It's up to you to decide when a decision should be escalated or when a consensus is needed. However, even in these moments it's your responsibility to be the tiebreaker.

What should this data model look like? The engineer coding it ultimately decides. What should the rate limit on this service be? The engineer coding it ultimately decides. Should we offer this as a one off feature or turn it into a dedicated suite of APIs? The engineer coding it ultimately decides.

This works because the person writing the code usually has the most context on the domain anyways, and if they don't, it's far easier for that person to learn the domain than for a non-engineer to grok the code. Becoming the domain expert should be a baseline expectation for the engineer doing the work.

This can often take some adjustment, since you may be trained to have an escalation path for every single decision (ex, a dedicated product manager, eng director, or other executive)[3]. Maybe in some cases, a lack of escalations can lead to a 10% worse design or outcome. But I believe that that trade-off is worth it since it's better to ship something quickly and get it slightly wrong than to ship something slowly but get it "right". There's no evidence that decisions made by group consensus are better than decisions made by a single owner with all the context anyways.

Almost too ruthless prioritization

It took me a while to realize that prioritization means pissing some people off. Software is defined by the things the engineers choose not to code.

Not gonna lie, this one takes exceptional leadership from a manager or CEO[4]. Ridiculously effective teams have ridiculous amounts of focus. My people pleasing tendencies would have me hiring more engineers just to throw bodies at what I consider P0 problems. It takes courage to say no to everything but the P0 among P0s.

A nice side effect of this is that nobody ever feels like what they are working on isn't important.

Hiring player/coaches

Hiring should be rare and special. You are bringing someone in to your circle of trust, a cherished environment that you've worked so hard to keep "great". How do you do this? There's no perfect formula here, but one mental model that I think works well is looking for the player/coach[5].

A player/coach is someone that can perform the work on the ground, but also has good instincts on how to lead and manage. This lets them manage themselves and take responsibility in a way that some pure "players" can't. Think about someone that will spend hours looking over crashloop logs in Kubernetes to find a networking bug, but also understands the reasoning behind the Q3 product roadmap. Player/coaches have the ability to zoom in and out and apply their skills for maximal leverage.

A player/coach is more a personality type than it is a specific amount of experience. They tend to be ambitious, but are ok with sharing the spotlight. They want to learn from others, but also value autonomy. They love leadership, but hate micromanagement. You generally want to avoid pure "coaches": people with fancy titles who haven't coded in a decade. These people are often too far away from the problems that the team faces, and as a result can't be trusted (see point 1) to make decisions (see point 2).

As you may imagine, it's very hard to find engineers that fit this mold. But when you do - the payoff is worth it.

Hard work as a default

Great teams work hard by default. As much as I hate to put this here, I can't deny that this is important.

There's a special joy in working super hard together as a team. The intensity and thrill of it is hard to describe, and can be addictive, often to the dismay of our friends and partners. I can often be a lazy person, but when working with a great eng team, that side of me disappears and is replaced with endless stamina and determination.

When you are trying to hit an insane customer deadline to ship a feature, or have a production issue wake you up at 2am, there's no better feeling than seeing one of your teammates log on to help you. Lamenting struggles and celebrating wins is way more fun when you've given it your sincere best effort surrounded by other people that have done the same.[6]

Part of working hard is knowing when not to work hard - taking vacations, switching up projects, caring for each other personally when times are tough. If hard work has to be a default, so does regular rest.

These 5 things aren't universal laws, just patterns I find useful[7]. Maybe there are great teams out there where none of this applies. If so, I'd love to learn about them.