On Seniority and Acceptance
There have been two hard pills for me to swallow as I've matured in my career, moving to more senior positions. By maturing I mean widening my impact from my individual contribution to the team level and beyond – being a multiplier, as they say. These hard pills are:
- You see more problems than you can fix.
- You can't expect a team to produce better quality than it knows how to.
To keep growing, I have needed to accept these new truths and adapt my approach. First, let's unpack these truths a bit before talking more of adapting.
(Terminology note: what I'm calling a senior engineer/developer in this post might be what other people call a staff engineer. Regardless of titles, I think a developer on a career path like mine will hit these topics some time along their career.)
ProblemsLink to Problems
Let me draw a caricature of a software engineer's relationship with problems along their career.
- Junior: I can see a problem, but I don't know how to fix it
- Mid-level: I can see a problem, and I know how to fix it
- Senior: I can see a lot of problems I know how to fix, but I can't fix all of them myself
The growth of an engineer in the beginning of their career has been all about getting better at solving problems. To become an independent contributor, one must independently solve most of the problems one encounters in daily work. Juniors are expected to ask for help, but also expected to learn and develop and eventually stop needing help.
A mid-level engineer can competently solve problems. However, their visibility is often limited to the task immediately at hand. They're thinking mostly about their own feature, not of their teammates' features, or the totality of the work of the team. As the engineer matures, they start to look more broadly at the work of the team. This means they'll start seeing more problems, but also new types of problems.
Firstly, there are all the immediate problems their teammates are solving, and the senior engineer can help with these. However, they can't help all of their teammates with all of their problems.
In addition, there are new types of problems. These can include things like inconsistent assumptions between teammates, unclear APIs, duplicate work, or quality problems. As the engineer matures, they'll start seeing even more of these, subtler and more nuanced problems. These kinds of problems are usually harder to fix, take more time, and can't usually be solved once-and-for-all, but need constant maintenance.
Thus: You see more problems than you can fix.
Quality and tasteLink to Quality and taste
Some of the new problems our developing senior sees are related to quality. Things like constant regressions in some part of the code, a flaky integration test suite, a crumbling separation of concerns between two components, etc. These problems can weigh heavily on someone who is used to excellence in their own work.
Also, as our senior has grown, they have developed a taste. They have certain ways of doing things, and certain things they like to avoid because they have been bitten by them in the past. Their teammates probably don't share the same taste – they have developed their own, or are in the process of developing it.
One way of trying to solve both of these issues is adding control and quality gates. Perhaps insisting on code review, a code style, a process or just watching over teammates' shoulders. I think we've all seen team dynamics like this. The team has grown, or a new team has been created, and the most senior developer wants everything done like they would've done it themselves. Code review takes many iterations. Nothing is ever good enough. They are trying to forcefully improve the quality. The results are clear: velocity and team morale suffer.
An engineer who is trying to be the arbiter of quality for their team becomes a bottleneck. If they want everything to be done up to a standard that the team just isn't naturally producing, it's the same as if there was no team, just one engineer. Also, focusing on one person's view on quality makes the team share all of that person's blind spots. Other, unseen, problems will crop up, and teammates won't react to them because they've been passivized by the control applied to them.
The hard truth here is that there are no quick wins for quality. You can't expect a team to produce better quality than it knows how to.
Improving the teamLink to Improving the team
What can be done? If there are more problems than can be fixed and better quality can't be found, is the project doomed to mediocrity?
Surely not, our senior engineer just needs new tools!
The key to working around both of the hard truths I've discussed is improving the team. Let me highlight the key parts:
- You see more problems than you can fix.
- You can't expect a team to produce better quality than it knows how to.
If we as engineers can inspire our teams to work with us to fix some of these systemic problems, it doesn't matter that we can't do everything ourselves. If we can improve the team's more junior members by mentoring, guiding, and giving them space to grow (by not standing behind their shoulder!), the quality output by the team will improve. It's not easy: giving the right mixture of support and freedom is difficult. But if we ask people, they might tell us what they need.
Improving the team is slow and uncertain work. We can't try to solve all of the problems we see at once. We need to really think about which problems are the most important, and which problems can't be worked on yet. Also, when it comes to more nuanced problems like quality and architecture, it can be hard to quantify the actual impact of the problem. Is the misleading API actually hurting the business? How much will a faster test suite improve work? Thus it's important to stay humble, and to work on these things in dialogue with the team, not as a dictator. Dialogue is a also a great way to get the team invested in solving the problems.
Even though improving the team is slow and uncertain work, the effort is worth it. Eventually, as the team as a whole matures, there will be multiple seniors to share the burden of the two hard pills. This will make dialogue within the team even more valuable, letting the team prioritize which problems to fix even more accurately. Also, it will be a lot less lonely than being the sole senior in a team.
We can also look at the topic of improving the team in terms of building culture in the team. But that is a topic for another day.
Acceptance and letting go of controlLink to Acceptance and letting go of control
With dialogue and involving others comes a final hard pill to swallow: letting go of control. As a developer grows from junior to mid-level, they have started relishing their feeling of control. They can solve the problems, they can make the decisions on what code to write. They are an independent contributor. However, as a senior, they must start to accept the loss of control: they can't control the team's quality, and they can't solve all the problems. They need to help the team, and let the team help them. The result is never exactly what our senior envisioned, but it might be something with even better outcomes.
Bringing in more perspectives from team members might reveal that our senior had been too focused on something (e.g. test coverage) while ignoring something more important (e.g. number of regressions). Having to think about the actual impact of things can let our senior analyze their taste. This means trying to move from subjective, intuitive judgments to recommendations grounded in actual risks and trade-offs. Whereas previously they just had some intuitions on how things should be done, now they can think about what actually matters, and what is just a matter of preference.
By the way, mentoring is a great way to both grow your team, and to sharpen your judgment on matters of taste. Really walking through the pros and cons of different approaches with your mentee and staying open to their suggestions will make both of you better developers.
Something that resonated for me was a comment on the internet along the lines of "don't break your back delivering something nobody asked for". I know I've often tried to make a test suite better than it actually needs to be, and pressed my teammates to do the same.
If letting go of control sounds weird, another way to think about it is prioritization. As always in software, we can't work on everything, so we must pick some valuable things to work on. To be able to accurately prioritize which problems need solving, our senior needs to move beyond the team level and understand what produces value in the organization. That might mean dipping their toes into the business side of things, interviewing stakeholders and users, and de-emphasizing technology for a while.
ConclusionLink to Conclusion
I'm still working on adapting to these hard truths as a senior engineer, but I think I've managed to accept them. This has allowed me to be satisfied with non-technical work, and to better understand my value, even when I'm not shipping features. One of the best ways to grow for me has been to mentor people, both teammates and co-workers in other projects.
I hope this post gives you some food for thought on your journey, especially if you don't agree with everything I wrote. There are many different careers in software, and I only know mine. I hope you have fun with yours!