Senior software engineers are expensive, and good ones can be fantastically productive. With the right support and environment, a good engineer can do great things, and with a dysfunctional environment, even the best engineers fail.
I’m not talking about beanbag chairs, espresso machines, and onsite massages. Great engineers love to make things, so 80% of the battle is just getting barriers out of the way- when an engineer wants to make great things for you, shouldn’t you let them? They may also want espresso, but lack of espresso isn’t an existential crisis. Lack of meaningful work is.
I’m also not talking about how to manage engineers. There are lots of books, blog posts, and seminars on how to be a great manager, and this is not one of them. If you’re a manager, I’m not going to tell you how to do your job. I’m gonna tell you what I need to do my job. A quixotic and personal list:
- Projects Scoped At Conceptual Level
- My task size: 2-10 days
- Our goals are defined, prioritized, understood, and as stable as reasonable
- I’m included early in decisions, with the movers and shakers
- Let me know how I’m expected to act
- Tell me who’s gonna do the OTHER stuff. What other stuff isn’t gonna get handled?
- Convince me
Projects Scoped At Conceptual Level
Senior engineers are expected to exercise a lot of autonomy and make a lot of decisions on their own. They should get sh*t done without a lot of back and forth. That’s only possible if the engineer understands the goals and tradeoffs.
If the spec says “implement autocomplete,” then the engineer can only implement autocomplete. If the spec is about “educating users about new search features by offering them as autocomplete options,” then the engineer can make intelligent choices about what the UI should look like, how to deal with edge cases, etc. Maybe what’s important isn’t “accurate” autocomplete so much as autocomplete that surfaces options the user might not know about.
My task size: 2-10 days
By task, I mean the smallest named unit of work that the engineer is responsible for. They’re the kinds of things an engineer might discuss in her one-on-one, such as “create infrastructure for autocompleting when user enters search terms, and add autocomplete to search control” or “fix all filed bugs for the next release.”
Small tasks, such as fixing a particular bug or changing some HTML, end up generating more heat than light. It’s inefficient to have to go back to your manager twice a day to figure out what the next task is. It’s also depressing to feel like you only work on trivialities.
On the other hand, tasks that are scoped too broadly (e.g. “integrate social media into the project”) allow the engineer to go off the rails or to get out of sync with others and with changing requirements. It’s also unpleasant- you feel like you’re not getting anything done. A senior engineer can be really helpful when trying to narrow a spec- they can help decide which features/tasks will best meet the goals, and they can help prioritize goals. But they can’t do that in a vacuum.
Our goals are defined, prioritized, understood, and as stable as reasonable
It’s pretty obvious that agreeing on goals is important- you can’t win a race if you don’t know where the finish line is. Prioritization is equally important, but less obvious. Suppose autocomplete is really technically hard, but pretty important. And rebranding is easy, but lower impact. So we decide that we’ll do the rebranding work first.
A great engineer might chew on the autocomplete problem while on a bike ride or taking a shower and come up with a brilliant solution that’s actually easy to code. The goals haven’t changed, but the engineer can start working on autocomplete right away- it’s higher priority AND easy. Alternately, suppose the engineer wasn’t privy to the prioritization discussion. All she knows is “we’re doing the rebranding, we’re not doing autocomplete.” Even a great engineer may not “waste” much time thinking about autocomplete when they know that it’s not in the cards. And even if they come up with the brilliant solution, they won’t start working on it ASAP (they may not even mention it to the right people.)
Needless to say, if priorities are changing on a daily basis, even the best engineer can’t make good medium-term decisions.
I’m included early in decisions, with the movers and shakers
You want your great engineers to understand your priorities, as mentioned above. For that, they need to be in on the ground floor. And of course they have a lot to bring to those discussions as well.
Great engineers have solved a lot of problems. They can steer an organization away from rocky shores, and towards safe and productive waters. They can turn the impossible into the possible. And they can point out when the emperor has no clothes (“wait, you say you want to ship it this quarter, and that high quality is crucial, but that we’re going to convert our giant Swing UI to HTML5? And it’s supposed to look identical?”) And they need to be on board with major decisions; hearing about the decisions afterwards isn’t enough.
A great senior engineer may be able to rescue a project that’s over budget and behind schedule due to poor technical decisions or flabby specifications. But that’s already a failure. Including senior engineers early in the design process can avoid wasted work and unnecessary expense, as well as averting a lot of anxiety. Further, nobody wants to be “the cleaner,” only called in once there’s a mess.
Let me know how I’m expected to act
Sometimes you want a senior engineer to rip through code like a tornado, blasting away all the old cruft and shaking the foundations. Sometimes you want a targeted strike- just fix this one super important thing and leave everything else (which has already been QAd) alone. Sometimes the code is going to be the foundation for lots of large projects, and sometimes it’s just short term fire fighting on code that will be replaced soon.
A good engineer can make sensible tradeoffs about refactoring, documentation, level of testing, etc. A good engineer can also decide when working 15 hours every day and skipping meetings and code reviews is gonna rescue the organization from an ongoing disaster, and when it’s just a death march that destroys organizations and products.
However, when an engineer and their manager don’t come to agreement on these issues, it can be disastrous. An engineer who thinks they’re building infrastructure may spend weeks or months on evaluating options and doing performance testing, only to find that once the (perfect) solution is delivered, it’s moot due to changes in the business. Rewriting the MVC framework from scratch may make everyone more productive, or it might piss everyone off (or both)! Sometimes, stepping on toes helps shake an organization out of lethargy, and sometimes it prevents productive teamwork. Engineers usually shouldn’t be making such decisions on their own (and won’t usually be rewarded for doing so), but great engineers will work with management to achieve organizational and business goals as well as engineering goals.
Tell me who’s gonna do the OTHER stuff. What other stuff isn’t gonna get handled?
Imagine that I’d like to change the routing rules in our load balancer. Bob’s in charge of the load balancer, and has to both approve and make all changes. But Bob’s on vacation, and he’s gonna be gone for a while. When he gets back, he might not like the change. In fact, maybe it’s a bad change- Bob probably knows best. Or maybe Bob just doesn’t agree that my project is important and worth the effort. How do I move forward?
“Bob’s curing cancer, don’t bother Bob, figure out some other approach” is a legitimate answer, and “Bob’s gonna need to get on board- just cowboy it in and Bob’ll have to live with it” is also a legitimate answer. But as the engineer working on the feature, that shouldn’t be my call. After all, I’m biased. I always think that my project is important and worth inconveniencing Bob. Someone’s going to get the short end of the stick, and that’s a management decision, not an engineering decision. If management decides that we’re gonna make a change to the load balancer (and Bob’s gonna make it), then I’m going to wait for Bob. Knowing when Bob is going to do it will help me plan my time. Maybe I don’t start working on that module until Bob sets up the load balancer in the test environment for me. Knowing that Bob is NOT going to do it is also liberating- it frees me up to think of a different approach. Waiting and not having a decision is poisonous. When I think that Bob’s going to make the change, but Bob doesn’t plan on doing so, that’s even worse.
I’ll walk through fire to save a baby, but I won’t walk through fire to save your iPhone. Your iPhone is important to you, but not to me. Convince me that the project is important (to the organization, to the world, to you), and I’ll go the extra mile. But if I basically think it’s a waste of time that’s unlikely to really make an difference in the world, I’m going to go home at 5 PM every day. I’ll still try to make great software because I’m a perfectionist. But it won’t be infused with passion. So spend the time to convince me (and convince yourself, if needed)! If it’s important to you, tell me why. Let me catch your passion- I want to! But if it’s not important to you, maybe we shouldn’t do it at all. Maybe we should use that time to figure out what IS important to us, and do that instead.
Thanks to Mitch Rudominer, Robert Gay, Don Hayler, and Topher Clark for their input and suggestions