Why They Pay Me The Big Bucks
When I started as tech lead at Limejump, it was my dream job. Finally, I was going to be able to actually lead a project's technical direction, rather than spend a whole lot of time arguing about how I thought it should work. As it turned out, this job was a whole lot more than that, and all of it has been a fantastic experience.
Now that I'm leaving though, I find myself having to explain just what my job is for those that will step in to replace me and I thought it pertinent to write this all down. Maybe someone will see it and find it useful, or maybe they'll call me out on my bullshit. Either way, the result will likely be net-positive.
The idea that as technical lead I'd be spending a big chunk of my time not talking to my team at all was a big surprise, but that's how this has worked out. Over the last 2½ years, a surprising amount of my work has consisted of communication with other teams, our product owner, my manager, and even upper management directly.
For the most part, a lot of the comms are about coordination. My team needs X to be finished by Team Y, so I'm talking to them about what they need to get X done. I can then later go back to my team and set reasonable expectations about the future, which will sometimes include a conversation about workarounds for the interim.
It's more than just harassing other teams about deadlines though. In many cases, I'll be asking for advice around what those teams are doing, what works best for them, what they might need from us or trying to arrive at a consensus of best practice across the company.
It goes the other way too. Other teams, when curious about what mine is doing, will usually just reach out to me directly. "Why does service X do Y? Can it do Z instead or as well?" This is a big part of my day.
If your team builds Something Awesome, but no one knows about it, it'll never be used, and so those efforts are effectively wasted. So part of my job is talking to other teams (usually just the nerds) and promoting some of the cool stuff we're doing. Maybe we've got a new library we think others might benefit from, or a new process for our CI that has improved things. Talking about this with other nerds earns our team respect and helps the company as a whole build on our experience.
Taking those Meetings Bullets
No one likes going to meetings, especially engineers who would rather be writing code. Honestly, I'd much rather engineers never have to be in any meeting they don't want to be in 'cause their contributions toward actually building things are much more valuable. To that end, if someone has to go to a meeting, I usually volunteer. It's my job to know everything about what my team is doing technically, so theoretically I should be able to advise on any subject related to what we're doing. Let the nerds do what they love instead.
When I became a tech lead, I thought I'd never be in a situation again where I had to argue with my boss about the right direction for things, but I've learned that as you move up the chain, you're still writing software, just through additional layers of abstraction ;-)
There have been a few times where upper management has made decisions that I've disagreed with. Whether it was a choice to keep an antiquated legacy service alive, or to migrate a bunch of systems to another standard, it's my job to be critical of things I disagree with.
Sometimes I've been persuasive, and other times I've simply had to adopt a position of "well, at least the truth is where it needs to be". I've even reconsidered my position a few times and gone back to my team to support the new direction. In any case, I think it's important that a tech lead speak out when they see the company doing something they think is wrong. It's basically a big reason they're paying us.
As someone who's not necessarily deep in the code but rather leading a team of people developing (19!) different projects, I'm in the unique position to be able to "mostly know what's going on" in a lot of different areas. As employee turnover churns, that knowledge becomes more valuable, such that on any given day, about 20% of my conversations are from newer colleagues asking me why something is the way it is and if it can be safely changed to do something else.
A lot of companies think that you can solve this problem with thorough documentation, but in a start-up atmosphere, where things are developed, tested, partially adopted, and then thrown away because of a discovered failure (move fast and break things!), expecting that everything be documented is a bit nuts. Even if you could document it all, no one would ever read it. Hell, if you've read this far into this post, you're probably in the 1%.
So, the best you've got in a lot of cases is good communication between your longer-running staff and the newer staff. Make sure people ask why a lot, so we can pass on lessons learnt.
Greasing the Wheels
My team is awesome and they all really know what they're doing, but sometimes they run up on something that blocks their progress. If that problem is political (management needs to fix something, or someone above needs to approve something) then they go to our engineering manager, but if it's technical they come to me.
I have a lot of days where I'll spend an hour or more with my nerds troubleshooting a problem, pair programming, or just fiddling with configurations together to get things working. Sometimes it's just me sitting in for some technical advice/guidance, and sometimes we're learning together. Either way, my involvement is usually only momentary, getting the engineers un-stuck so they can carry on being awesome.
Probably my favourite part of this job has been the mentoring. I've worked with some really brilliant people at various stages in their careers. With 23years behind me, I get to play the "Elder Nerd" and talk about "that one time where I worked at a company where X happened".
The key thing here for me is that you have to put the interests of the person you're mentoring over the interests of the company as a whole. If you don't, they'll know it and they won't trust you. I think I've managed to cultivate a reputation where people know that I'll always be straight with them, and that's allowed me to have some really great conversations about personal and career development. I've also made some great friends.
Much of what I do as a technical lead is not technical direction at all.
Imagining the Future
This was the most daunting part of the job when I applied for the role. I figured I was a pretty good coder, but could I actually lead a team? Why they hell would anyone follow me? I decided to look back on all of the tech leads I'd had over the years and apply the good stuff (obviously) but also look deeply at the truly terribly bosses I'd had and decidedly do the opposite.
To that end, I didn't direct the team at all. Instead, I spent months just getting to know the team, the context, and the various codebases we were responsible for. Over time I started to sketch out a diagram of where I thought we should be and updated it daily through various conversations.
After all that time, I had a pretty good idea of where I figured we should be going, but critically I never tried to impose that vision on the team. Instead, I used it to inform my conversations with them and slowly nudge us in the direction I wanted. The idea was to make sure that the team as a whole decided to go in a direction collectively with some guidance, rather than just slapping a diagram on the screen with "Ok kids, here's where we're going!"
Some concessions were made of course, but they were never treated like battles won or lost because there was never a battle at all. We decided, as a team to build things this way. I've been really happy with the result, and I believe, so has the rest of the team.
I don't write a lot of code these days, but I review tonnes of it. With a team of 5 other engineers churning out multiple PRs each a day, I'm usually the one going through that code.
For the most part, I'm not looking for bugs. Instead, I'm trying to make sure that the code is:
- Safe: Have we made any decisions that could leak data or pose a security risk?
- Does it conform to standards?
- Is it needlessly clever?
- Can someone who's never seen this code before understand what it does easily?
- Does it violate the principle of least surprise?
- Is it self-documenting, or do I need a probably-out-of-date document to understand it?
- Tested: I mandate 100% test coverage, allowing for explicit exceptions that must be defended during review. This may sound extreme, but the result is code that can be regularly and easily updated. On our projects, a complete Django update takes about 1hr of developer time, while at previous companies it was weeks or even months of work combined with a lot of fear & uncertainty.
- Performant: This is where I get to say things like: "We did this at Y company back in the day and it didn't go well, maybe try Z instead."
I also try to give some time to questions around broader architecture. Should we be storing this code here, or should we instead be moving it into a different folder or even an external library or service? Sometimes these questions are more meant for later conversations though.
The pattern we usually follow is that unless there are "show stopper" bugs, security flaws, or violations of any team standards, I usually mark the PR as "Approved" and let the engineer decide if they're going to implement any of my suggested changes. It's a collaborative effort, and engineers shouldn't feel like their tech lead is writing their code for them.
However every once in a while someone writes something that I just think is a Bad Idea. It's not that the code is bad, but rather that it takes the wider codebase in a direction I'm not comfortable with.
This is a Hard Problem for me. In these instances I struggle with balancing what I think is the right direction for the project and making someone on my team feel like they've wasted their time, or worse, that I think they're a bad engineer. What follows is usually a dance of egos and an attempt to find some middle ground, which is not always possible.
This sometimes is a battle, and in the end, someone will have to give a little. I like to think that I've been reasonably conciliatory, but I guess I'll leave it up to my colleagues to be the judge there.
Humans aren't ants. We need a reason to keep going, so if you work at a job that feels soul-crushing, you won't work there very long if you know what's good for you.
I can't take credit for this idea, as I'm pretty sure that Rob, our perpetual team sunshine inspired this, but I'm a big proponent of it:
If you write the code, and I review it, it's not your code anymore. It's our code.
A lot of companies talk about "no fault retros" or a "culture of shared responsibility", but in 23years I've never seen it done as well as we've managed in our team. Somehow, we've managed to foster this culture of collective ownership to the point where we carefully choose our pronouns when talking about our work.
- "The server fell over when it received X"
- "We made a change last week to call Y when X was received"
- "Alright no problem, let's make a ticket for this so we can patch it up for tomorrow's release."
If someone tries to claim ownership of a bug or failure, someone always reminds them that they didn't cause this problem, we did. The result is a team that celebrates individual and collective successes and takes on failures as a shared burden.
Sometimes things suck. Sometimes there's a load of work ahead, or a colleague has left, or a project was killed. Whatever the cause, as the lead it's at least partially my job to try to keep spirits up, to make what needs to be done feel achievable.
Honestly, this is one of the harder parts for me as it always feels forced. I mean, I'm usually a rather emotional and animated person, but it's hard to step out of myself and try to illicit a particular feeling in others, especially if it's for the benefit of a company rather than a person.
The same goes for good news though. Pitching a subsidised night out to management when a project is delivered on time, or even just to acknowledge the efforts of individuals is a pretty great part of the job.
I used to have a tech lead that would regularly lament: "I didn't even get to write any code today!". As one of his engineers at the time, I thought that this was a pretty weird thing to get worked up about. After all, I was writing code all the time and it wasn't that great.
You start missing it though. If you're in a job where you're only ever looking at other people's code and not writing any of your own, you get... itchy.
I'm in stand-up every day, and I try to regularly take a ticket and hack away on it throughout the week. This work generally takes a back seat to everything above though, so I try to avoid taking any work that might require a lot of time or upon which other tickets depend so I don't end up blocking anyone.
Usually, I try to sharpshoot tickets whose work will inform future development, so that I can establish what I think are good patterns for what's coming down the pipe, but it doesn't always work out that way.
Finally, if everything else is accounted for, I try to do a little of what I affectionately call "gardening": the process of looking at existing code and creating a pull request to make it a little more stable, performant, or just developer-friendly. Most of the team is focused on churning through tickets, and sometimes improvements are overlooked: typos in comments, missing type hints, somewhat kludgy ways of doing things that could be a lot cleaner and simpler if afforded the time and attention. On days when I need a break, I do some gardening, create a PR, and ask that someone review it when they've got a moment.
And that's it. That's my job. It's a whole lot more than I expected it to be when I answered the recruiter 2½ years ago, but to be honest, I really like it. It's kind of the perfect middle ground between hands-off management and hands-on trench work, and I wish more companies followed a model like this.
At my next job, my title will be "engineering manager", but as I understand it, the role won't be all that different, just with added line-management responsibilities. This probably means I'll have even less direct code access, but that's fine by me. I can satisfy the "itch" with some Free software projects. 😆