Before: Good Cross-functional Team/Bad Cross-functional Team
News at Reco! Soon - exactly 1 next month from when I’m writing this blog post - we’re rebuilding our R&D structure. Part of the change means that ownership of delivery is mostly on me: essentially updating my title to VP R&D (from VP of Engineering), temporarily. I say temporarily since I’m sure that we’ll change again and again. The exciting part is that we’re building a structure of 4 cross-functional teams, and growing the group members a lot faster. This is a big move for us, and I want it to succeed.
I’m writing this before we start - hopefully, I’ll report back about what worked well and what didn’t.
I wrote this document to help the group visualize how will good teams look. I want good teams, they want to be good teams, but what does that mean? I work with very strong people; I don’t want them and me to become frustrated by everyone interpreting their job differently. I recently read “The Hard Thing About Hard Things” which had a chapter called Good Product Manager/Bad Product Manager. The “Good X Bad X” format seems perfect for this goal. Let’s give it a go!
Some lingo and context: Every team is made up of an Engineering Manager (EM), Product Manager (PM), and team members (designers and engineers of different professions). The teams are focused on a specific use case with E2E responsibility from market to release. We stick to Twilio’s “PM & EM: Rules of Engagement”: The PM is in charge of Why and What; The EM is in charge of How, Who, and When.
1) Leadership Unity
In a good team, the EM and the PM will always answer similar answers when asked the same question, even if internally they disagree. In a bad team, the EM and the PM are not synced. They answer differently when asked the same question.
1.1) Good example
VP R&D: I see that we think that this feature will take 3 days without tests. Why are we skipping tests?
EM: Releasing the feature is really relevant to a customer call later this week.
PM: Of course, we’re aware that this is technical debt - we’ll take it into consideration in the next few sprints.
1.2) Bad example
VP R&D: I see that we think that this feature will take 3 days without tests. Why are we skipping tests?
PM: EM said there’s no other way, and I have to release this now.
EM: There’s no chance that this will work without tests in time, but PM said we have to cut something to make it in time.
2) Professionalism
In a good team, every team member understands all the details of what they’re working on. Team members learn and grow in relevant ways to the team. In a bad team, team members assume that someone else did the thinking for them, and they only need to work.
Note: Technical folks in teams need to make sure that non-technical members can do this as well. Be inclusive! You’d be surprised to learn how many engineers mistake the ability to code with the ability to think.
2.1) Good example
Dev: We’re going to need to re-think the DB schema here, perhaps even replace it. This design bug might set us back.
PM: Could you help me understand the issue?
Dev: Sure! The tables aren’t normalized correctly and we’re querying a table with a filter, so the sum of the table rows will not be accurate.
PM: OK. Gimme a second. [opens Google]. Wait, for this screen, an estimate number is accurate enough, we don’t have to be exact. Will that help?
Tech lead: Yeah! We can skip the refactoring for now if an estimate is OK.
2.2) Bad example
Dev: We’re going to need to re-think the DB schema here, perhaps even replace it. This design bug might set us back.
PM: OK. I’m pushing the roadmap back 1 week.
2.3) Professionalism as the primary source of influence
In a good team, team members that are specialized in a specific field (e.g., UX) make sure to explain themselves to an extent to make sure other team members understand their work. In a bad team, specialized team members say things like “we’ll do what I said because I said so and I’m the UX”.
3) Alignment
In a good team, the team can do everything it needs to do, without harming the efforts and roadmaps of other teams. In a bad team, the team delivers while breaking other teams’ packages, pipelines, tests, product flows, and UX principles.
A good team aligns with other teams when it’s useful, and figures out how to operate independently at all other times. A bad team aligns to cover their own asses, wasting time and attention.
3.1) Good example
Dev [x]: I think we might have made the tests 2 times slower with this new DB, and this impacts many packages that are not in Team [x]. Refactoring this will take us a week…
EM [x]: Can we refactor our own logic to a separate package, so that the dependency graph will be less clustered? That way our slow tests will not impact other teams. And creating a new package only takes half an hour.
Dev [x]: Nice!
3.2) Bad example
“Not my problem, no one’s problem”:
Dev [x]: I think we might have made the tests 2 times slower with this new DB, and this impacts many packages that are not in Team [x]. Refactoring this will take us a week…
EM [x]: Not our problem. Let’s release. If it will bother other teams, they can fix it.
“Not my problem, everybody’s problem”:
Dev [x]: I think we might have made the tests 2 times slower with this new DB, and this impacts many packages that are not in Team [x]. Refactoring this will will take us a week…
EM [x]: Let’s set up a meeting with the other teams and decide how can we solve this.
4) Product and tech debt
“‘Cause when you in my position, it ain’t ever easy to do any type of maintainin’
‘Cause all the gamin’ and famin’ from entertainin’ is hella strainin’ to the brain and
But I can’t keep runnin’, I just gotta keep keen and cunnin’”
~ Runnin’ by The Pharcyde
Functionality
/ \
Schedule <-> Quality
Choose two.
4.1) Enginners
In a good team, devs find clever ways to utilize tech debt and take ownership of loans that they take. Devs will prefer to come up with and implement solutions to debt instead of complaining about it; that means that they influence the EM and PM in a positive manner to get the relevant budget to pay off the debt. In a bad team, the only entity that is impacted by tech debt is the Jira issue key counter, but you somehow never stop hearing about it.
4.1.1) Good example
Dev: There’s an interesting opportunity here. I think we can delay building a generic interface here in favor of just releasing. I already wrote down what’s the future design, but implementing it later will save us some time.
EM: When will we fix this?
Dev: Not now, but I wrote it down in the PDR of the next feature and also pings PM about it. I’ll make sure we don’t forget to refactor this when we expand.
PM: Thanks!
4.1.2) Bad example
Dev: Ugh, this non-generic interface fucking sucks. I have to copy-paste a ton of code, again.
EM: Can we solve it?
Dev: There’s a ticket. [puts headphones back on]
4.2) EMs
In a good team, the EM knows when to take loans for now, and when to pay them off for the future. In a bad team, the EM is extreme in one of two ways: always deliver shit fast, or always deliver super-high-quality code, but never on time.
4.2.1) Good example
Dev: The tests are really flaky, it makes releasing hard.
EM: I see that we have a few days between the next release and until the next round of user research, and the designer is on vacation, as well. Instead of getting a head start on our next feature, can I take the team to fix the flaky tests?
PM: Well, how long will it take? And why do we need to fix this?
EM: Longer than you’d like, but it will cost more in the medium term if we continue accruing this debt. Running manual tests wastes time.
PM: OK. How can I help? Need help redefining tests?
4.2.2) Bad example
The “no debt” EM:
Dev: The tests are really flaky, it makes releasing hard.
EM: No releases until we fix the tests.
PM: What? Why?
EM: It won’t work otherwise, I can’t work my team members so hard on features for so long!
PM: Well, OK… How long will it take you?
EM: Until we finish there’s no feature work, period.
The “no future”, “hero mode” EM:
Dev: The tests are really flaky, it makes releasing hard.
EM: We’ll just have to work harder to run manual tests. Clear your weekend.
PM: Please, don’t work the weekend! I can talk to the customer to push the commitment…
EM: Nah, it’s fine. We’ll just work harder. We can also skip every odd test this release, and every even test next one. I’ll take on-call in case something doesn’t work.
4.3) PMs
In a good team, the PM knows when to push the team to deliver under budget at the cost of debt, and understand when it’s a bad pick. The PM also senses how much they can push the customer to use sub-par features. In a bad team, instead of balancing a budget, the PM is extreme.
In a good team, the PM generates simple options to take. In a bad team, the PM looks for easy solutions.
4.3.1) Good example
Customer: Hey, this screen that you released last week is great! I’ve been using it almost daily. It’s kinda slow, though…
PM: Thanks so much for the feedback! I’m not sure what’s the cause of the slowdowns, but we’ll get on it soon and let you know.
[Later…]
PM: The customer loves the feature, great work! How can we improve performance?
EM: Well, we can solve it specifically here, but there’s some tech debt with how we’re deploying the caches generally. We should probably investigate it at some point.
Dev: Yeah, the cache is a bit of a mess. We can fix it here, but it will be annoying again next week…
PM: Let’s solve the lowest hanging fruit so the customer feels the product is improving. That way we’ll gain enough confidence (and time) to start the research.
4.3.2) Bad example
“Just solve it”:
Customer: Hey, this screen that you released last week is great! I’ve been using it almost daily. It’s kinda slow, though…
PM: Sorry! I’ll talk to the developers and solve this ASAP.
[Later…]
PM: We have to improve the performance now! The customer complained about responsiveness.
EM: Well, we can solve it specifically here, but there’s some tech debt with how we’re deploying the caches generally. We should probably investigate it at some point.
PM: Just solve it now, I don’t see why it should be hard.
EM: The short-term solution won’t scale well. Caches are error-prone and hard to debug.
PM: We have to solve it now. If there’s an easy solution, let’s do that and move on.
“I don’t know, so it’s impossible”:
Customer: Hey, this screen that you released last week is great! I’ve been using it almost daily. It’s kinda slow, though…
PM: This screen operates slowly because, well, [buzzwords].
Customer: Well, if [buzzwords], OK.
5) Working with cross-organizational teams
A good team cooperates with cross-org teams with proactive adoption and avid feedback. A good team shares as much credit as possible with the tools that cross-org teams built for them. A bad team mistakingly thinks that the cross-org team works for them instead of with them.
A good team wants to become more empowered using the cross org teams’ output. A bad team drifts towards becoming more dependent on cross org teams.
6) Teamwork
In a good team, everybody is eager to help everybody else. They genuinely care about the success of their team members. They reach out if someone seems stuck, and provide professional timely feedback all the time. In a bad team, everyone worries about their local Maxima, not the global maxima.
In a good team, devs invest in code reviews to teach and learn, not only to find bugs. In a bad team, code review is just a checklist item.
7) Estimations & commitments
Shit happens.
In a good team, when delivery times are missed, everybody works together to understand why and see how to recalibrate the commitments. In a bad team, instead of looking for root causes and action items, team members are trying to find who to blame.
This is important: good teams tend to succeed, and then they get MORE tasks, resources, and promotions. “People like to help those that help themselves”: and companies like to grow groups that grow themselves. Bad teams tend to fail, and then they don’t try to “help themselves”; and the company prefers to put its resources someplace else.
In a good team, the title doesn’t impact how much care about the output. In a bad team, you only care about the output if your title says you should. Specifically, the EM is in charge of how, who, and when; But the team must understand that the delivery is the team’s main responsibility.
7.1) Good example
VP R&D: Seems like we’re not going to deliver on time. What gives?
PM: We’ve already opened a retro document. The requirement scope was way too big for this version.
EM: We also had an unexpected architectural bug with the API, which set us back a while. We have to look at streaming VS client-server at the next DDRs, not just assume that client-server is the default.
PM: Other than these points, EM and I discussed and we think we’ll release the first phase in 4 days. I had to talk to the customer; they weren’t happy, but I managed to smooth it out with them. Here’s the breakdown of what the release includes…
EM: Here’s who’s gonna work on it and how we’re going to develop it…
VP R&D: Sounds like a good plan. I can get a contractor to just on the migration development; will that help?
EM: Yeah! We can probably shave off 2 days with that.
7.2) Bad example
VP R&D: Seems like we’re not going to deliver on time. What gives?
PM: I don’t know what to tell you - development is delayed. Customers need the feature now. It’s not OK that development hasn’t been on time.
EM: Yeah, we hit unexpected stuff, we didn’t plan for it in time.
VP R&D: What now?
PM: We should release on time.
EM: We can’t release on time, I have to work nights to make this happen on time.
PM: Well, I committed to the customer. I’m not moving the date.
VP R&D: You’ll have to figure this out within the team.
8) Different methods, same goal
In a good team, the PM should aim to solve a customer pain in a short time, while the EM wants to increase velocity and push the team all the time. In a bad team, the PM and EM are fighting over who’s right.
9) Summary
A good team is a good, meaningful, and satisfying place to work at. It’s worth thinking about how to make your team better. A bad team is a bad, meaningless, and unsatisfying place to work at.
I hope I’ll succeed in building good teams, and fail at building bad ones.