Over at simplermachines.com Nat Bennett published an excellent draft article on what management at Pivotal was like. Every choice comes down to trade-offs. As Nat pointed out, these practices originated in a consulting environment. I want to look at what practices translated well into other contexts and why or why not. Hopefully this will allow others to pick the right practices for their organization. Unless you are already familiar with Pivotal management practices, you should first read Nat’s article for this article here to make sense.
A little refresher on my own background might be valuable context: I was an individual contributor as a consultant at Pivotal (Labs) from 2010 till 2013 in SF and then returned as an Engineering Manager, also consulting, from 2015 to 2017. In 2017, I joined the product team at GemFire where I became a director later that year. A role I kept with some title changes till my departure in January 2024. I loved working the canonical Pivotal (Labs) way when I was a consultant. That was easily one of the happiest times in my career.
Backlog Management
The backlog traditionally was populated by the Product Manager with the help of the anchor and engineers would simply pick up the top story from the backlog.
This works really well if the work can be broken down into user-visible, vertical slices. This should be true for most products. If this is hard to accomplish, I’d argue that the accelerated feedback loop and clarity this brings to prioritization is worth the additional thought that needs to be put into defining these vertical slices.
If your product requires large amounts of work in the background to facilitate a change visible to the user, involving the Product Manager in granular story breakdown work might not be the best use of everyone’s time. GemFire is a distributed, in-memory store and many of our stories fell into this category. Work like “Support JDK 17” or “support parallel recovery from disc stores” require very little Product Manager involvement during story break-down. Arguably you don’t want them involved for much of it, since they decide the “what?”, but the “how?” is up to the engineering team. The only questions for the Product Manager might be if it’s OK to require the user to set certain flags during startup and some other simple usability questions, mostly around configuration.
To address this we moved the Product Manager engagement to a higher level for much of our work at GemFire. Their time was better spent thinking about the strategic decision-making, communicating with customers, etc. The break-down of these larger features and day-to-day backlog management was moved to the manager. Which brings us to the next topic…
Trade-offs
Small, user-visible, vertical slices ➡ The Product Manager owns the backlog
Large, technical efforts that have minimal user-visibility ➡ Engineering team owns the backlog day-to-day
There is also an entire article here that could be written about bug management.
Team Structure
In the traditional Pivotal model Engineering Managers coded 80% of the time and weren’t on the same team as their reports and staff rotated frequently between teams. For us this didn’t work out for multiple reasons:
Technical Complexity Resulting in Long Ramp-Up Times
GemFire’s code base had a lot of complexity, inherent and incidental. This lead to long ramp-up times which made rotating between teams and areas of the code base expensive and frustrating for newer engineers. This was most clear on the team that built our CloudFoundry platform offering which was co-staffed with CloudFoundry engineers. Engineers from the CloudFoundry side would usually be rotated off once they were properly ramped up and were able to hit high productivity levels. This model seemed to work well on the CloudFoundry side where much of the used stack was the same between projects, but all the complexity around deploying the highly stateful GemFire offering made it a different beast.
I personally loved this model when I was a Pivotal Labs consultant and mostly worked on Rails apps. The fact that Rails had an opinion on how to solve 95% of issues a typical web app will have allowed developers to hit the ground running day 1 on any new project. This also resulted in frequent exchange of best practices whenever a new team member joined. The projects were similar projects that did different things, rather than different pieces of the same larger thing.
Unhappy Team Members
It’s interesting that it seemed that CloudFoundry engineers and Pivotal consultants (myself included) enjoyed frequent team rotations while our GemFire engineers did not. This even held true for engineers who came from CloudFoundry and permanently joined GemFire. I am not sure if I fully understand what caused this.
I think the longer ramp-up times definitely played a role. However, this seemed more pronounced with people who were working remotely. Building relationships to your team members is harder when you are remote, and you get close to zero exposure to people on other teams which makes a move to another team a much more disruptive event.
“Debugging” Teams
At one point we had a team that was perceived as underperforming. I was the Engineering Director for the team and ended up spending probably about a dozen hours or more trying to figure out what was going on. I ended up having to talk to the anchor, Product Manager, some individual contributors and multiple managers, since different team members had different managers. It did not help that this particular team seemed to have a culture of “not snitching on each other”. This became much easier when we changed structure and everyone on the team reported to the same manager who was responsible for their team’s delivery.
What We Did
We moved to a more traditional model with managers generally managing a small number of teams. We aimed to keep managers and their reports on the same team. On occasion, we’d need to move some engineers to other teams for temporary efforts. This was most frequently the case for more senior engineers who’d help rescue a project or brought some special expertise that was needed for an effort. This worked pretty well for teams that owned smaller, clearly separated parts of our code base (client libraries, plugins, etc.).
On the large, main code base this was a bit messier. Feature efforts typically took months and then nobody might do any feature work in that area for a long time. We kept trying different models. Ultimately what likely worked best was having a group of feature temporary teams that were stable while working on a feature and all reported to the same manager under the umbrella of a larger “core”-team that had a single manager. I don’t think this was perfect either, but maybe it was the best solution given our situation.
Trade-offs
Similar projects that do different things and low unique, technical complexity ➡ Consider frequent rotation to share best practices and increase individual learning.
Low similarity between projects and high technical complexity ➡ Lower value and higher cost from frequent rotation.
Summary
What trade-offs and practices are best for you and your team depends on so many factors. My rule of thumb would be that if your project is ships frequently (you should if you at all can) and much of your work is immediately user-visible, you should start with the default Pivotal way of organizing the backlog and adjust from there to your organization’s needs as you learn more. I’d be more hesitant on rotating team members. This will largely depend on the work the individual teams are doing, the technology involved and possibly even on where your teams are located.
There is probably a lot more to be said here. Since my blog doesn’t support comments, feel free to hit me up via Twitter, email (see sidebar) if you want me to dig deeper on anything.