A few engineers I’ve managed in the past have recently asked me for material on “changes I have done in teams”.
They were being kind. What they were referring to is more honestly described as my frequent rants about a few principles I believe in.
This might be useful for other people out there. So I wanted to write down a few principles. But more than that, the ways I’ve seen teams work against them and practices I’ve used to change.
Before we start, nothing here is new or groundbreaking. These are concepts I’ve learned and seen practiced more than 10 years ago. And if you are looking for a more high level view of principles of software development, I do recommend this post by Evan.
From my perspective, managing software teams is about productivity and reliability. Agile made software development simpler. But there are three components that are often forgotten: You have to prioritise, you have to be iterative and you have to focus on finishing work.
A tale of another team
Multiple times in my career I’ve seen teams working this way:
A product person defines work in cards. They will write requirements from the business/user perspective, which define what needs to be done.
And engineering lead divides the cards in technical tasks. The lead will analyse the cards and decide the technical approach. This approach will be explained in many technical tasks.
Technical tasks are distributed amongst engineers. To create accountability, engineers get tasks they need to get done and work through them individually. These are usually sorted by technical expertise. If Sara knows about this part of the system, she gets the tasks that touch it.
It goes downhill from there. Stand up meetings become status reports about a single task that no one has context on. The product person has no visibility on how much work is actually done. There is a hope that it will come together at the end, but the end is continuously delayed.
Improving it with principles
Whenever I see the situation above, I think back to a meeting I had at my time at ThoughtWorks. It was about a project not related to software development. When the problem we had got summarised, I turned to the person next to me, asking how could we deal with it.
His answer was both simple and memorable: “We do it as we do it with any problem. We analyse it, we divide it in small independent pieces, we finish and verify each one of them”.
It was simple because it was how we solved any problem in the company, both internally and with clients. And it was memorable because it helped me reduce this big unknown question in my mind to a series of steps I knew how to do.
The thinking above led me to the following principles. I have applied these to pretty much all teams I have worked with:
The first thing is that priorities need to be clear. Have only one backlog of items and rules about what gets in and out of the backlog. All items in the backlog need to be business / customer focused items that can be delivered and verified independently.
Don’t drop the ball. Have one (or more) engineer(s) working on one piece of work at a time. Feel free to get help / switch people around if the work gets complicated, but don’t drop any piece of work. Cycle time is the measure to optimise for (it’s not the only one, but the one that will make the most difference).
Get it done
Done means having a piece of work delivered and verified by who asked for it (hopefully in production). The whole team is working together to get there, and people need to help each other with their skills and expertise.
Is this everything you need for a team to be successful? No. But it’s a good chunk of it. As Brian Guthrie has summarised better
The secret sauce of software development — the philosophical origin of most advancements in thinking over the last 20 years — is incremental change, tight feedback loops, shared knowledge, and mutual respect.
Some common tactics
All the above might be great, but how can it be achieved in practice? While this is a non exhaustive list, here are some practices I keep applying to teams in order to get to the principles above. If you feel like your team has similar challenges, give it a try.
Change the way you do stand-ups. Stop focusing them on people (what I did yesterday), and focus them on work (what’s happening with this card). These are also known as walk the wall/board stand-ups and are not a new thing.
Priority is right to left, top to bottom. Make it clear that engineers (and the rest of the team) should prioritise cards closer to being finished from starting new work. Make stop starting, start finishing the mantra for choosing what to work on.
Don’t tell engineers what to do. Don’t create technical tasks for other people to follow. If engineers need guidance, give it to them as they are starting to work on something in form of a conversation, not as a to-do list of less meaningful technical tasks a week in advance. Engineers are smart and make hundreds of decisions a day, the more context they have on work, the better those decisions are.
Don’t assign work in advance. While teams do that to incentivise accountability, it creates a pressure for individual work over team work. Soon enough is hard to help each other and it makes the system slower.
A piece of work is something the business understands. Don’t settle for cards that are written for engineers. It’s part of the job to deliver work that a non technical person understands and can verify. Pair on testing/verifying cards.
Triage defects and measure time spend on them. Context switching and distractions are the main productivity killer. Triage bugs when they are raised and create hard rules for what is ‘urgent’.
Track. Cycle time and where the team is spending their time. You will be surprised by results.
I think that’s all. Or at least most of it.