Leadership Principles for Engineers
August 24, 2022
Introduction
Career growth as a software engineer can be tough to navigate, particularly if you’re inclined towards building things and reluctant to go all-in on engineering management. Many companies provide a career ladder with clearly delineated manager and IC tracks. I’ve found this creates a false dichotomy betwen leaders and builders, and doesn’t provide much clarity for builders. In my current role, I spend a fair amount of time speaking to engineers with varying experience levels and tenure about career growth, and have found myself circling around a few themes and mental models for growing as an engineering leader.
By growing as a leader, I mean developing our capacity to lead, expanding our impact beyond individual output, and acting as a force multiplier on our teams. Great leaders do not always wield authority, and they may not always hold formal organizational responsibilities. Many great leaders have no interest in becoming engineering or people managers, and that’s OK: engineers at all levels can and should cultivate their leadership skills in order to grow their impact and foster a healthy engineering culture.
What follows is my list of engineering leadership principles: these are the attributes I’ve found throughout my career in the colleagues I admire most and that I personally aspire to. I hope folks find them interesting and are able to use this framing to reflect on their own professional growth!
Build Trust
Mutual trust is a pre-requisite for any successful shared endeavor. Feeling psychologically safe; taking comfort that our teammates know and accept our flaws, even as they challenge us to grow; being able to set boundaries and navigate conflicts productively; taking our team members at their word: these conditions allow us to focus on building solutions and reaching higher truths, above all else.
As a junior engineer, you build trust primarily with follow-through: when you say you’re going to do something, you do it. You also build trust through honesty and humility: you admit when you fall short, and don’t exaggerate achievements to gain recognition. You build trust by showing curiosity and listening openly to understand other perspectives.
As you become more established, you might gain trust by being vulnerable: you share your failures and self-doubt openly. You identify issues in collaboration and address them head on, with curiosity and empathy. You show up for someone in a crisis and help bail them out without judgement. In both formal and informal settings, you open up to people around you, and bring quieter folks into the conversation. Finally, you foster trust by speaking thoughtfully about other people, striking a balance to be vulnerable and share openly, but avoid disparaging others to enhance your status.
As you reflect on your professional growth, ask yourself: how am I contributing to building trust on my team? What can I do to better understand and connect with the people I collaborate with? How can I change my approach to navigating conflict to foster more trust? Should I revisit any aspect of my behavior at work that erodes trust?
Manage Complexity
The world is messy, and human and software systems are rife with internal contradictions. The reason our systems don’t collapse under the weight of their contradictions is because each engineer carries some of that cognitive load with them, and is constantly striving to ease that burden through cleaner abstractions and new designs.
As a junior engineer, you manage complexity by remembering those shortcuts we took in the last class implementation, which will get cleaned up when that other team delivers its new API. You write down documentation to help other teams understand a thorny system behavior which we can’t yet afford to fix. You help someone in your help channel navigate an integration process that’s a bit confusing.
With more experience, you can manage complexity by holding deep, esoteric knowledge that fuels operational excellence and helps us mitigate imperfections. You might be the person who deeply understands the edge cases in a piece of legacy code, or the operational characteristics of an open-source technology that has a tendency to fall over.
At a larger scope, managing complexity is often about holding architectural and organizational tension. You track the fundamental ways the details of your micro-service’s design don’t live up to the idealized diagram, and propose a long-term fix. You observe the three teams currently building things that are incompatible with a long-term vision, and chart a path to long-term convergence. You collect signal on recurring operational issues caused by an organizational gap, and find ways to mitigate while advocating for a staffing or prioritization change.
In each of these examples, engineers wield their expertise and know-how to smooth over gaps and imperfections in our systems. They do this in a way that doesn’t just hide problems: they take ownership over the imperfection and hold the tension in their minds for how that thing eventually gets better. If they are trusted to do this well, whether at the level of a few classes, a code base, or an entire initiative, they free up cognitive load for their colleagues, who can tackle dysfunction in another area.
As you navigate your growth, ask yourself: what technical area do I fully own, in terms of understanding its nuance and shortcomings, freeing up my colleagues to do other things? What can I do to grow that coverage? Do I have a plan to make things better, or am I just propping up dysfunction?
Sustain Motivation
In the face of entropy and shifting requirements, building software can be demoralizing. This is particularly true as systems mature, when the accrued value of the existing software is so large that the cost of change becomes daunting. How do you stay the course in the face of a hard, multi-faceted migration that will take two years? How do you sustain belief in the new technology you’re introducing, when it’s falling over in production and customers and leadership are losing faith? Engineers have a huge part to play in sustaining this motivation.
For a junior engineer, you primarily sustain motivation by staying engaged. You participate in discussions, you’re curious about problems, and you’re willing to pitch in wherever you can be helpful. Your enthusiasm fuels motivation and overcomes cynicism. You also sustain motivation through your work ethic: you grind out a challenging implementation and approach code review with humility and patience.
As you become more experienced, you sustain motivation by overcoming big obstacles or injecting velocity. You pull a late night and show up with a nicely factored implementation for a tedious change that everyone was dreading. You push through a bunch of end-to-end test scaffolding that allows others to iterate more quickly. You write a clear RFC that overcomes concerns about a messy technical decision. You run a key meeting where you empathize with another team’s concerns and reach a consensus that unblocks progress.
Regardless of experience level, you also sustain motivation by understanding and making space for your teammates’ passion. You take extra time to explore alternative implementations on that tricky code change with your teammate who loves code craftsmanship. You articulate the business impact of a change, or arrange a customer meeting, for the teammate who is driven by business impact. You take moments to step away from your work and celebrate big milestones and recognize good work.
In each case, you wield your collaborative energy, technical skills and talent to sustain motivation for your team. You inject optimism and a sense of possibility into otherwise daunting projects. You inspire others with your pace of implementation and ability to overcome obstacles, encouraging them to also bring their best. As you reflect on your growth, ask yourself: what am I doing to sustain motivation on my team? Do any of my behaviors detract from this goal or demotivate my colleagues? How could I change my style of working, or better wield my existing skillset, to create positive energy around me?
Seek Higher Truths
Engineering done right is more than a grind towards a goal or a struggle against entropy: it should also be elegant and beautiful! As we work through problems we should be developing higher-order abstractions and a more fundamental understanding of our problem space. Great engineering means constantly seeking and synthesizing signal around you to re-evaluate the technical ideal to chase.
This is the tragedy of our profession: if we do it right, we never reach the finish line. As we progress towards the current goal, we expand the scope of the problem to solve, and therefore need to generate a new mental model and a new north star. In applying that technical rigor and constantly challenging our heading, we ensure that we build sustainable, compounding value in our products.
As a junior engineer, you seek higher truths by engaging on your project’s fundamental abstractions, and asking questions about its purpose for being. You speak with colleagues from other teams to exchange ideas and discover new approaches. You’re engaged in the broader industry, and try to connect trends you read about to your day-to-day work.
If you’re more experienced, you’re turning over systems in your mind, and refining your mental model for what they do and how they connect to the bigger picture. You seek out diverse voices who may uncomfortably challenge your views, and seek to understand the gap. You write roadmap or vision documents to articulate a technical ideal. You iterate with peers on other teams to ensure your technical visions are aligned.
It’s our responsibility as engineers to step away from the day-to-day and ensure we are building something meaningful and innovative. As you reflect on your growth, ask yourself: how can I grow my participation in technical truth-seeking in my team or group? How can I allocate time outside the chaos of day-to-day implementation to reflect more deeply on where we’re going? How can I seek out new and challenging ideas that might disrupt the status quo and overcome groupthink?
Grow Your Peers
The best way to guarantee you work on a great team is to help others around you grow. If you do amazing individual work but don’t accelerate the growth of your peers, you’re missing out on a big opportunity for impact.
The first step here is often code review and whiteboard sessions. You have some expertise in a workflow or a part of the code base, and you help the next person understand how that thing works. You understand your teams’ core products, and are responsive and helpful when people have questions you can answer.
As you become more experienced, your code reviews become richer, and you impart hard-won wisdom about best practices and patterns to follow. You might help other teams understand the broad architecture of your product, and how their work fits in. You work with someone on their first cross-team RFC, and provide early feedback to help them nail the engineering review. You partner with another engineer on a large project, and allocate tasks selflessly to optimize for their engineering growth along the way.
Growing peers is also about feedback: you let your teammates know when they let you down, and take the time to articulate how it made you feel. You grab coffee to talk through a code review that didn’t go well, and offer your advice on how to approach the next task.
As you reflect on your growth, ask yourself: how can I leverage my existing skills and preferred style of work to grow others on the team? What adjustments could I make to share knowledge or develop skills? Is there any feedback or advice on my mind that I’m currently not sharing with teammates?
Conclusion
When thinking about engineering excellence, we’re often anchored on coding skills, knowledge of technologies and tools. In my view, those are table stakes: necessary but insufficient to drive excellence. Software engineering is a team sport, and if you want to play at your highest level and be exposed to novel, challenging problems, you need to figure out how to foster healthy teams around you. So: Build Trust. Manage Complexity. Sustain Motivation. Seek Higher Truths. Grow Your Peers!