I’ve had several conversations lately about how to organize development teams, enough so that it’s probably useful for me to write out what I do think here. By no means should you think for a second that my shop or my team is perfect and I’ll happily admit that much of the focus here is on things that I want to be different at work.
This would have been a much longer post, but I found worlds of older blog posts I’ve written on this subject. Honestly, the problems I see and the solutions I’d recommend just haven’t evolved that much in the last 10 years. I don’t know if that makes me worried more about myself or the software development world.
- Call me a Utopian, but I want my teams flat and my team members broad
- Self Organizing Teams are Superior to Command n’ Control Teams
- Once Upon a Team
- The Anti Team
- On Process and Practices
- Want productivity? Try some team continuity (and a side of empowerment too) – I miss this team.
- The Will to be Good
- Learning Lessons — Can You Make Mistakes at Work?
- Indelible Proof of a Healthy Team
On Software Teams (2007)
Multi-Disciplinary Team and Multi-Skilled Folks
I think it’s a huge anti-pattern to organize software teams around technical specialties or disciplines like having a UI team, a middle tier team, and a database team. I’d even go farther and say it can be a negative to keep the testers somewhat separate from the rest of the development team as well. I think the main point is that each team should ideally have every skillset it needs to carry out the project inside the team room or at least under the team’s control.
Moreover, autonomous teams that can do everything needed to carry out the project are far more likely to succeed than teams that have to frequently depend on other teams or technical specialties. Formal hand-offs between teams in software development are an almost inevitable drag on productivity and should be minimized as much as possible within a software organization.
You will make mistakes and discover last minute requirements or flaws in your architecture. Sure, you can try to do the very best planning possible to ensure that you know everything upfront, but my experience says that you’re far better off when you can easily recover from mistakes and accommodate those last minute discoveries. Needless to say, it’s far easier to be flexible in last minute discoveries or problems if you can just fix the problems yourself. What’s going to be faster, filling out a Jira ticket to get a database team to add a column you need or being able to just add a database migration to your codebase and continuing on your way?
Even without formal hand-offs, keeping developers in strict specialties can easily make it harder for the team to communicate with each other because there is less common concepts between team members while simultaneously requiring more communication because every feature has to involve more people. Not every developer can be a multi-skilled generalist, but at a minimum, each developer needs to have some understanding of how the folks both upstream and downstream of them work and what their concerns are. My early career was actually spent as an engineer designing petrochemical plants, and one of the earliest lessons my first manager drilled into me was how important it was to understand what the other engineering disciplines did so you could better support their work with your products and how to more intelligently ask questions of the other types of engineers you depended on.
Making developers specialize by technical concern can frequently lead teams into the Local Optimization Fallacy trap. If you’re not familiar with this, think of cases where the developers optimize some part of the system for how themselves, but that decision makes the tester’s jobs much harder. On the flip side, it’s frequently advantageous to do some extra work inside the code for no other reason that to make automated testing much more efficient. In many cases, you’ll save more time in testing than the extra time you spend coding, and that’s a net win for the team.
Specializing personnel on teams can be bad for developer growth and skills acquisition. My current shop has historically kept the database team separate from developers, and frequently the outcome has been developers who don’t have a good background in the basics of database development and database developers who maybe don’t have a solid appreciation for other software engineering principles.
Everybody Knows Where the Bodies are Buried
I’m familiar with several teams who own and maintain codebases that were originally written by other people and they frequently struggle understanding how things flow through the system or even the basic architecture. Somebody is going to say they needed more documentation and I’ll say instead that companies pay a high price for not having some developer continuity when the tribal knowledge walks out the door. Either way, it’s absolute vital that the team truly understands the codebase they’re working on.
Arguably, one of the most important jobs of a technical lead is making sure that the other team members understand how the system is designed, the basic technologies, how information flows through the system, basic domain concepts, and how to troubleshoot problems throughout the stack.
We’re admittedly struggling in many cases with gobs of legacy technology decisions that aren’t familiar to many of our developers (partially because we hired a prolific OSS author and his old tools are every which way). The long term solution is to replace those tools with more modern, commonly known tools. For now though, it helps somewhat to try to explain why those decisions were made and what the original team was thinking as a way to better understand how to work in those codebase as they are today.
How Microservices Might Fit In
Honestly, the big value proposition for microservices in my shop is mostly being able to move to a world where each codebase is small enough to be completely owned by no more than one normal sized team. We have 3-4 big systems that are worked on by multiple teams, and let me tell you, the folks on those teams have absurd Git skills just able to manage having so many developers contributing simultaneously.
Forget the Golang or Node.js powered microservices with under a 100 lines of code, I’ll settle for most of our teams getting to work on a codebase that is:
- Small enough to be completely owned by a single team
- Small and simple enough that mere mortals can reasonably understand the codebase
- Has a relatively fast automated build because that’s a huge component of being productive