Management is a fickle thing. At least from what I’ve seen, it’s usually something learned through experience as much though theory.
And it’s not for everyone. I’ve made a real point to create pathways for people to advance without needing to make the leap from writing code to spending their time wrangling people. One of my favorite YouTube channels has a great video summarizing research in this vein, looking at whether sales teams promote the right people. That research suggests the usual way of making promote-to-management decisions is wrong: strong individual performance may even be anti-correlated with performance as sales manager.
When I first tired to create a pathway up for individual contributors, though, I was met with some pretty reasonable pushback: how do you decide someone is at a higher level as an individual contributor (IC)?
There are easy ways to get a handle on this for people managers. While imperfect, if you simply count up the number of people who ultimately report to that person, it’s a fair gauge of how much leverage they’re getting. All else equal, manage 100 people and you’re likely having more impact than someone who manages 10 people.
Figuring this out for people who don’t manage anyone is less straightforward. Or at least less obvious to me.
You really don’t want to look at something like lines of code written. The best engineers I’ve ever worked with tend to write fewer lines of code than their more junior counterparts, for example. (I’ve often given people callouts for how much code they’ve managed to delete from our codebase, and that tends to be the better engineers on the team.)
Eventually, I settled on a framework shared by one of the more senior engineers I hired. The better the individual contributor, the better they are at anticipating problems.
What does this mean?
For better or worse, entry-level people create a bit of chaos as they try to make progress. We’ve all done this. You’re overconfident or not sure what you’re doing, bash some code together, and, while it works, you did something very strange you didn’t fully understand to a Kubernetes manifest. When your code gets deployed, the cluster is misconfigured and a feature breaks because there aren’t enough replicas of your service to handle the user load. This is fine: it’s the only way to learn certain lessons.
As you move up, you should be anticipating problems at a greater and greater scale. That might start with starting to spot potential corner cases in code review. At higher levels, you may see potential issues that could have an existential risk for the company. Maybe spotting a really subtle but potentially terrible security vulnerability. Or realizing you need to switch to a sharded, replicated database product from the single-instance Postgres you started with, and charting that path forward.
Very roughly, you might summarize level mapping like this:
Entry-level: creating more problems than you solve
Senior: solving more problems than you create
Staff: anticipating problems at the team or department level
Principal: anticipating problems at the company level
Fellow: anticipating problems at the industry level (e.g., developing a new widely-used programming language that spans multiple companies)
Of course, these different titles have different meanings to different people. Maybe you prefer to reserve the “Senior” title for something more, well, senior than someone with a handful of years of experience under their belt.
I like this framework because it’s both easy to understand and dovetails nicely with the idea of getting leverage.
Because, what does it mean to anticipate a problem? It means getting more work done, more efficiently. If you have the wisdom and expertise to realize that a project should be written in Rust rather than C++, that could save huge amounts of time and money and remove tremendous risk. It’s a lot more expensive to build something in C++, then realize afterward you shouldn’t have done that only after someone has exploited a C++ memory model issue to steal a bunch of passwords.
Spotting something like that, without even writing any code, you’re helping to deliver more. You may have saved an entire team of people from doing three months of completely wasted work.
At the extreme, if you’re the author of something foundational for an entire industry — think of PyTorch for neural network models or Swift, a new programming language — that’s an astonishing amount of impact and leverage. Using something like PyTorch has saved people millions or billions of hours and enabled huge numbers of projects that otherwise wouldn’t have been feasible.
Not everyone is cut out for management. Not everyone wants to be a manager. That’s OK: we’re all much better off having incredibly strong people continuing to contribute code directly rather than managing people. But they need a path they can follow. For those of us who are in the leadership chair, we need a framework that balances our responsibilities to the business with our stewardship of people’s careers. While I don’t think I’ll ever come up with a perfect framework, as a guiding principle, I think this one works well.
Bonus: A Video Worth Watching
As I continue tinkering with this format, I thought I’d toss in a little bonus. I really enjoyed this lecture with Eugenia Cheng at the RI in conjunction with her new book, The Joy of Abstraction.
Enjoy this? Have an idea for something you’d like a perspective on? Drop me a line: I’d love to hear from you.