Building Better Software Teams
Table of Contents:
There are three fundamental tiers of team-based work within organizations; while this article will be focused on improving software engineering teams specifically, many of the thoughts contained within are broadly applicable across industries. The first tier of team-based work happens within single teams, and is limited to the people that make up that team (and how they work together). The second tier occurs as teams inevitably collide — learning to work across functions, perhaps, or with handoffs across divisions. The third tier is the inevitable coalescing that occurs between individuals, teams, and entire divisions & companies. The third tier is the most nebulous; as companies grow larger, the relationships between different parts of them tend to ebb and flow. Just as in chaos theory, the closer we look at these units working together, the more self-similar they appear — that is, the more teams appear as the integral unit of measure, and the people within them.
Let’s start from the beginning, then: with the first tier, and how to improve upon it.
It’s rare to get the opportunity to hand-pick a team. It’s much more likely that your experience working within engineering teams is an expression out of this variety pack:
- you’re hired or put onto a pre-existing team as a leader
- you’re hired or put onto a pre-existing team as a team member
- you’re put onto a new team after having worked on another team without you (or anybody else appointed to the team) having much in the way of a say about that
- you decline to be put onto a new or existing team due to various factors
All of that is to say that greenfield opportunities where you (either as the team leader, joint team leader, or as team member) are able to have much of a say in the composition of the team. In some consulting roles, I’ve been lucky enough to be able to decline teams and roles when I felt they weren’t the right fit for me (last bullet point), but I don’t take that sort of privilege for granted and don’t want to assume that’s at all commonplace.
So what makes a great team, individually? There’s been a glut, over the past few years, of articles appearing on engineering forums about the “myth of the 10x developer.” Any large-scale social uprising that can easily be seen and measured, like this, provides our first interesting data point when considering the composition of what consitutes a great team to work on: you probably don’t want to work with software divas. 1
Here’s my list for the best characteristics to look for in teammates:
- capable of nurturing an environment of mutual respect and empathy
- naturally curious
- diverse (geographically 2, in gender, nationality, etc…)
- passionate about collaborative work
It’s not a huge list; it’s also not rocket science. Diverse teams perform better. They’re also simply (in my experience) more fun, and having fun at work (while not a requirement) is a major plus to strive for.
In other words, the best teammates aren’t selfish. They’re generous, caring, and inspiring. They understand that everyone has bad days. They’re not part of some “elite” list — they’re regular people trying to do their best every day, and trying to help you do the same.
But, as I’ve already said, most people don’t get the chance to handpick all or even some of their team members. That means it’s even more important to manage upwards when it comes to your expectations for present & future teammates; to proactively select for companies that have excellent Diversity & Inclusivity programs if you’re planning a move between organizations. I’ve been inspired by the work Chelsea Johnson and Julian Joseph - you should hire him! are doing to promote these measures within our own industry; hopefully you know of and are promoting other champions in this area.
For most of us, team compositions are relatively static; the same thing that (hopefully) provides us with stability and comfort also means that friction is slow to disappear. As the adage goes:
“Trust is a fragile thing - hard to earn, easy to lose” - M.J. Arlidge
What we want and what we get are frequently at odds, and given how much of our lives are spent working, it’s not hard to understand how frustration can creep in when “dealing” with difficult teammates. I put that word, dealing, in quotes to emphasize what it feels like. Still, there are a few things we can do to continue our own learning journeys and to foster a healthier team dynamic:
- always assume good intent on behalf of others
- don’t shy away from standing up for your beliefs (this can be extremely daunting, difficult, and at times unpleasant)
- always practice using non-violent communication principles. I’ve talked about the importance of these principles in The Life & Death of Software; in many ways this article is a continuation of that one.
In particular, here’s a quote from Non-Violent Communication Principles that’s resonated with me many times:
Emotional Audit: Check in with your body and identify adjectives that describe the sensations you’re feeling. Are you hurt? Scared? Joyful? Irritated? Choose words that are specific to your experience - not words that insinuate what another is doing. Describing your feelings as being overlooked, devalued, unheard or pressured all suggest that someone else is doing something to you and won’t foster mutual understanding. Choose these words very carefully.
Whether you’re a people leader, individual contributor, or even just a casual passer-by — never be afraid to celebrate and protect the sanctity of a great team. Change is good, and change is constant. That doesn’t preclude you from enjoying and savoring the work that you do while on a high-performing team. To all those out there who currently work on and enjoy working with their team (and I know I do) — cheers! This one’s for you. Take a deep breath in. Hold it. Release it slowly. When you’re ready, we’re ready to explore the next section together.
As it applies to engineering, the best traits manifest themselves in a variety of ways. Great teams are constantly getting feedback, both from within and from without. Responding to that feedback with humility and openness is a defining characteristic of great teams and team members. Teams are self-organized; they may be cross-functional, or apply for help from subject matter experts when necessary. Either way, they come up with working agreements that idealize their preferences in a balanced way. If that means that they only work collaboratively, great! If that means everybody works asynchronously, also great! The entire spectrum between those two things is also great; what’s important is agreeing on things.
This extends to team-specific conventions around code reviews. Our team, for example, loves code reviews. We’re always delighted with the review process, and frequently amused with the number of things we discover we’d like to fix. I’ve talked about this on Move Fast, Don't Break Things, on the Salesforce Developer Podcast, but I also acknowledge and recognize that there are many teams that hate doing reviews. There’s room for compromise here, even if you personally are excited about reviews and your specific team isn’t. It might mean that you go in search of mentorship elsewhere in your organization, or outside of your organization. It might mean that you seek out knowledge in a different way. I’m always a proponent of faster feedback — if you can get feedback on code review as soon as possible, that’s vastly preferable to waiting. And that’s true for both parties. No “expert” — regardless of how good they are — is going to be able to provide great feedback as the backlog of code to review builds up; this is exactly why security audits that are performed on startup codebases are expensive and take a long time to perform. Expecting an outsider to come in and keep themselves up to speed over the course of months sets both you (and your team) and them up for disappointment.
Reasonable expectations — which we’ll talk more about it in a bit — are key. I’m a big fan of “kaizen”, or continuous improvement. We try to identify at least one thing that we could improve upon at the end of each sprint. We’re not always successful at that, and that’s ok! It’s been my experience that the mere act of introspecting on how things are going, and where they can improve, is frequently enough of a course correction for a team to remain high-performing over time.
It’s possible that you’ll have some people on your team more passionate about one particular area of code, or responsibilities, than others. Good teammates see the ability to complement each other when interests diverge. Maybe one person is really passionate about DevOps; maybe somebody else is more interested in implementing theorems or patterns. Each area of specialty brings the sum to more than the whole of its parts.
“Cross-functionalism” (experientially diverse) teammates collaborating has been at the heart of (small “a”) agile from the very beginning. So has the need for teams to work together. I’ve spent the past year branching out, both within Salesforce and within the larger Salesforce community. My goal was — and is — to foster better relationships between my team and the teams we work with. As I alluded to above (sticking up for your beliefs can be daunting), treading the line between evangelism (“collaborative work means faster feedback!”, “mob programming allows us to shift left on more than a few things that teams struggle with!”, etc…) and relationship building not only can be hard work — it’s pretty much always hard work.
One of the things that’s become more and more apparent? Teams that work well with other teams have people on them that excel at planning. They can take a single visonary phrase, like:
- reduce our cloud compute costs
- create this amazing feature
- implement observability according to these SLOs
And work backwards from the vision to work that’s well-scoped. Planning takes time, and effort. It takes trust in the ability for seamless handoffs to occur — trust, there’s that word again! 😅 — trust that as projects (and the number of teams working on them) grow in size, delegation becomes more and more necessary. Apple wouldn’t be nearly the company it’s become without Steve Jobs’ influence. But there’s also no iPod, and certainly no iPhone, without hundreds of engineers, and dozens of teams, being able to come together. Delegation becomes the name of the game.
The more time I spend working with engineering teams, the more evidence I’ve seen for the necessity of delegation:
- when work is handed off between teams
- when plans are made between teams
- when leaders plan for upcoming work
Proper planning is an artform. It often starts months — and years! — before any engineering work is done. This isn’t the rebirth of Waterfall; rather, it’s the actual beginning of true agility. This is perhaps my favorite quote on the subject:
“Plans are worthless, but planning is everything” - former President Dwight D. Eisenhower
Eisenhower also famously said while addressing the Naval Academy:
“But finally, there is one other quality I would mention among these that I believe will fit you for difficult and important posts. This is a healthy and lively sense of humor.”
Which dovetails nicely with what I was saying about the importance of having fun at work. But back to planning — what I like about Ike’s quote is that it foreshadows the birth of the (big “A”) Agile movement. Responding to change over following a plan is sometimes used out of context to justify a lack of planning, but within that very tenet of the Agile Manifesto is the implication that there should be a plan. Which leads me to my next point.
Self-organizing teams with great planners tend to succeed. But, as a leader (just as with individual team members, and between teams as well), it’s important to get feedback early and often in the process of delegation. That feedback ideally is part of the original planning process: defining success goals to pin projects to. It’s increasingly common for SLAs and SLOs to form the long-term “success metrics” for teams and teams of teams, but no plan is complete without discrete and measurable ways to judge the success of upcoming projects. The more concrete a goal, the easier it is for planners to translate visions into actual products; it also helps to be realistic.
Going back to our “reducing cloud compute cost” example, it’s unrealistic to try to set a goal like “80% reduction in cost over 2 years,” unless you’re being wildly extravagent already. Even a 10% reduction might be too much to ask for, depending on the compositional nature of the spending. Leaders typically work with planners upfront to understand what’s possible, and then pin their goals accordingly. Concrete, achievable numbers help to keep teams on track, and incentivize them to help one another achieve the broader goal. Arbitrary, seemingly unrealistic numbers can be demoralizing; since the goals feel unachievable, teams tend to insulate themselves at the cost of missed handoffs and costly delays.
There’s also another, hidden, silver lining that comes with success metrics. It’s one that I’m surprised isn’t talked about much given the shorter shelf-life of many software projects these days: the sense of relief individual teams can take solace in when a treasured project is sunset. Knowing that your team(s) met or exceeded the stated goals for a project can be a major source of redemption for people, and can frequently transform what would otherwise be burnout and indifference into an acknowledgement of relative success even when something ultimately “fails.”
There’s no proven way to scale. I remember reading Spotify’s Scaling Agile shortly after it was first published more than a decade ago. At the time, I was an outsider looking in — a key stakeholder for a few tech teams, but nothing more than that. It seemed incredible that Spotify — a company I had barely heard of a few months prior to the paper being published — had already scaled to several dozen teams while I was watching progress get bogged down between a bare handful of teams.
I think the LogRocket tech blog has a good take on the various kernels of wisdom the past decade+ has assigned to Spotify’s infamous take on scaling, and both the original paper and that article are worth the read. I’m of the mind that learning about your own organization’s growth and stability is always productive, especially if there are ways to become more active in what ends up being an ongoing conversation.
Going back to how teams are formed, though, I’d hazard to guess that most of us don’t work at early-stage startups, which means that most of us also won’t see large changes in our organizations. One of the central tenets of chaos theory is self-similarity; that the closer you look at something, the more it looks like what it was based on. People are the cornerstones of strong organizations, and in my experience the best companies try to prioritize their people. Some of that is handled by benefits. Let’s look at some of the other ways people can be prioritized in organizations.
The best companies I’ve worked at have distinct, well-understood career ladders. This empowers employees to carve out their career progression, envision future successes, and understand how to funnel their energy into productive, valued work. This leads to satisfaction and retention.
The worst companies I’ve worked at don’t publish career ladders; they also move goal posts, set false promotion deadlines, and generally try to drag out the process of promotions as long as possible. They’ll use any negative feedback as a means for blocking promotions. This kind of gaslighting, which I’ve talked about before, has the opposite effect — it leads to dissatisfaction, poor retention, and (concomitantly) encourages only poor performers to stick around. 3
This one can be hit or miss, but mandatory continued education can help organizations to promote employee connectedness, reinforce central plans & goals, and keep people abreast of shifting landscapes in themes like security, company core values, and the progress of ongoing initiatives. In addition to what we would think of as “classic continued education,” where a company offers benefits for private educatonal opportunities for an employee, we can think of continued education as a form of giving back to yourself by enabling you.
Volunteering becomes the other side of the “giving back” equation — enabling others, and creating community in the process. I’ve been incredibly inspired by my coworkers and leaders over the past few years in opening my eyes to the number of possible volunteer opportunities out there, and I know many people that can personally attest to the sense of satisfaction that being able to give back produces.
Whether you’re in the rare position of getting to hand-pick a team, seeking to be the best possible teammate and colleague, or looking to improve upon your existing working relationships, hopefully there’s something for you here. Building better teams takes hard work, empathy, and a commitment to non-violent communication. I really want to emphasize the hard work aspect of it — in this day and age, it’s easier to talk inspiration in online “soundbites,” but that does a disservice to the actual commitment and level of effort it takes to create, maintain, and foster great relationships at work (and in life)!
Whether you’re beginning a career in software development, at the mid-point in your career, or starting to wrap up your working life, take the time to introspect on how your own role works with others. Do some journaling, if that’s your thing. I did this recently and it was fun to look back on the last 13+ years of working; what’s worked for me, what hasn’t worked, moments I wish I’d handled things better at work, moments I know acknowledge I probably didn’t need to work (as) hard. Reflection exercises like this are what led me to actively seek out mentorship roles in prior organizations, and to continue that work here at Salesforce. If you do end up reflecting, be sure to let me know! I’d love to know what ends up coming up for you, as well.
As always, thanks to Henry Vu and the rest of my sponsors on Patreon. Your continued support and encouragement means a lot to me!
There are way too many articles to list out about the 10x developer myth, and I'd encourage you to seek them out. You may very well know developers that you consider to be "10xers", and my intent in talking about the backlash isn't to dispel the fact that there are some very hard workers out there who repeatedly show off an ability to learn and retain information at a high rate. Rather, my intent is to show that the mere existence of such people has led to a "cottage industry runoff" where many people claim to be a 10xer rather than focusing on actually growing their skills; be wary of such people.↩ go back from whence you came!
Published research on distributed teams was scant prior to the pandemic. Take this paper, for example: - one of the few. From 2020 onwards, published papers explode: Virtual Teams In Times Of Pandemic, Team Dispersion and Performance, etc... note that the research is mixed, though all teams that work collaboratively excel regardless of being colocated or not↩ go back from whence you came!
"Brain drain" is a well-documented condition at the country level, but it's also been studied at the company level as well, particularly over the past few years. Consider this report as an example, which details how companies can best combat brain drain by keeping their employees happy. Sound familiar? There's a plethora of intriguing studies published on this subject.↩ go back from whence you came!