What makes a great senior engineer? This post explains how we look at that at Otovo.
The intended audience are software engineers and their managers:
- Engineers who are curious how to move up the ladder of seniority: use this post to climb in the right direction.
- For senior engineers to recognize what’s important to do your role well, to improve yourself where necessary, and to help your colleagues grow in their role.
- For managers to help teammates become better engineers.
I explain six areas we at Otovo consider important to learn thoroughly for our engineers. I explain them intentionally with few details, because you have a lot of room to wiggle. There’s not one specific senior engineer archetype; we do want, and encourage a diverse crowd, with various traits, perspectives and opinions. Having that in the company increases the range of skills available, and that’s useful for the variety of tasks we set out to solve.
Let’s begin 🤗 The areas I explain are:
- Understanding the business
- Building others
- Working together
- Being responsible
- Technical skills
We don’t expect you to excel in all of those as a requirement for senior roles. Few people will ever master all of them. Use the areas as inspiration to define goals for yourself where you can, and want to grow further. Help your manager to help you by asking them for guidance.
Photo by Todd Diemer
Understanding the business
Climbing the seniority ladder takes time. Not because time automatically leads to seniority; it takes time because experience and reflection are vital parts of what separates junior and senior engineers. Experience includes exposure to technical subjects such as playing with programming languages, building APIs, getting frustrated because things break and feeling the joy of achieving something great. Experience also includes recognizing how your work affects the business and the users. Understanding where your work fits in the bigger Otovo puzzle, and which other parts of that puzzle you should care about and focus on, are important realizations on the path to being a senior engineer. Use your curiosity to ask questions to soak up knowledge from the people in the company. Befriend product managers, stakeholders to the team, people in adjacent teams, and utilize their knowledge to figure out how things work outside of code and technical aspects. Work to understand why things are as they are in the company, where we plan to go and why we’re going in that direction.
As you gain experience and seniority, a bigger chunk of your time should be spent on supporting others. Invest time in teaching and use your knowledge to help people through their challenges. Guide rather than giving instructions. We encourage learning from failing; let people stumble, but ensure they don’t fall too hard. Have patience; you may solve tasks more quickly—and write code faster—than your colleagues today, but your goal is to change that. You’re successful when you make others faster than yourself.
Other people’s opinions will differ from your own. Seek to understand others’ viewpoints before being understood yourself. You’ll find that people open up as their authentic self when you meet them with warmth, understanding, patience and empathy. People that dare to be authentic are more likely to come up with bright ideas: give people room to be geniune and candid.
Ask for feedback on how you perform in your role to understand how others perceive you. Consider adjustments based on what you hear. Give pedagogical feedback to others. Praise often, never blame and don’t delay the difficult conversations. Teach from your wisdom and experience, but be prepared to discover that it’s sometimes flawed or outdated.
Inspire others by being the role model you look up to, or the one you wish you had.
Photo by Annie Spratt
Together is better
Acknowledge that complex problems are best solved in teams. Master the balance of involving the right number of people. Too many cooks make a mess, but too few can reduce the resilience of the product. Different opinions and conflicts may reduce your speed short-term, but the product will be better when built with diverse perspectives. Speak up where others should be involved, and likewise when we’re too many. For example, ensure affected stakeholders are involved when your team plans a feature. Make sure they are informed and ready when you launch it.
Clear communication is critical for success in teams because ideas matter only if you’re able to transfer them to others. Accept that it’s your responsibility to communicate better when people don’t understand you. Work to be concise and unambiguous. Speak up if you disagree, and commit when we have decided; including when you don’t fully agree. Encourage discussions, and be part of building a culture where it’s safe to express ideas and concerns.
Be mindful that stakeholders don’t necessarily understand the technical implications of what they ask for. Many features are not worth the implementeation- or maintenance- cost. Work to suggest a compromise in such situations. In the myriad of requests, help the team choose the most economic tasks by weighting cost and business value. Split up tasks into chunks of deliverables to faster learn how the feature performs and how users find it. Use that knowledge to choose which adjustments to do in the next deliverable.
Photo by Dim Hou
Be dependable and make sure you’re on time. Delivering fast is great, but being predictable is more important; the trust you’ll get is immensely valuable. It gives you more freedom in your work, and the people depending on you won’t spend energy being concerned that you won’t deliver. Strive to be trustworthy. Escalate surprises you can’t handle as they arise. Stakeholders and the team should trust you to deliver what you promised on time, and that you communicate unforeseen hurdles immediately.
Take responsibility for complete delivery. Clarify what done means with your peers, product people and stakeholders. You may think a pull request gets the job done, but your stakeholders won’t care until it’s live and usable. Similarly, your peers may require some sort of knowledge sharing such as documentation or a demonstration.
We move fast and you’ll be part of the ups & downs in the company. That sets the stage for rapid learning, and will be rough at times. We expect senior engineers to take care of teammates, and help ignite the team’s motivation; also in challenging times. Don’t forget to take care of yourself too. You’re in for the marathon, not only the sprint. Embrace your vulnerability by asking for help in tough situations. Others may open up too by observing you being vulnerable.
Many at Otovo have their role for the first time. We all want to do good, but we don’t always know exactly how. Grab the opportunity to help us improve, and lead the process. Ask for responsibility—or just take it—instead of waiting for someone to give it to you. Remember that stumbling/failing is not only OK, it’s part of your learning process. There’ll always be more to fix than you have time for, so be selective. Ask a colleague if you’re in doubt about priorities.
Take initiative for starting bigger tasks. For example by organizing a kickoff gathering for stakeholders and the team. Tasks usually require a continuous momentum or else they die slowly: react quickly when you recognize things slow down. We want the train to keep moving 🚄
Make sure you understand feature requirements. Recognize what you don’t know and find the answers. Avoid (dangerous) assumptions by asking questions. Regard questions as a way to learn more rather than not knowing enough.
Look out for obstacles and surprises, particularly in uncharted terrains. Get help to understand issues before they arise. Don’t stay stuck in a problem: ask for help or take a step back to get an overview of your problem, your feature, code or whatever it is. Sometimes, you just need a break to get unstuck; consider a walk, a shower or unplug with some nature.
You’ll get many urgent tasks; not all of them are important for the company. Work on the correct problems and practice the art of saying no. Choose important over urgent. Some tasks are both important and urgent; be prepared to stop what you’re doing and gather your crew immediately to fix those. Don’t assume others will fix a system when it breaks in production. If you’re not yet capable, find someone who is and use that person to learn how to be capable the next time it happens.
Pushing bugs to production will happen and is fine. But if you break it, you fix it. Be vigilant and alert after pushing code to production.
Build for the future: care for long-term implications such as maintainability, security and performance when writing code. Write tests to avoid regressions. Learn how modules and systems integrate and what their responsibilities are. Help others understand how, and where, data flows by, for example, ensuring architectural documentation exists and is up to date.
Work to understand where to best place code in our architecture, and tune the architecture when it doesn’t fit. Dig for the root cause of a problem before jumping on a band-aid process that’ll just postpone a bigger explosion. However, remember that not everything needs to be perfect: balance pragmatism and flawlessness by choosing what’s best for the company.
Your craft can solve many of our problems, but it’s not always the right tool. Carpenters with a hammer don’t see all problems as nails and neither should you. The best solution to a problem sometimes lies outside of your expertise. Some problems are better solved by third party tools, and others by tuning work processes rather than changing code.
Code is run by machines, but read by people. It’s written today, read tomorrow and maintained for years to come. Choose readability over conciseness, and use best-practice patterns to shape what you build. Read your code from the perspective of others. Improve the code style and patterns where necessary. However, there’s high value in consistency: improving the code style of one module can sometimes lead to more confusion if the other modules are still done differently. Ensure, therefore, to complete what you start.
Help to build the right product by leaning towards data-driven decisions rather than decisions based on intuition, gut-feeling, empathy and anecdotes. Break down problems and use it to ship iteratively to learn fast. Don’t forget to breathe: it’s better to plan one extra hour than wasting three.
Technology is meaningless until it’s used to solve problems. Separate technology from the goal rather than being the goal itself. Avoid over-engineering and be skeptical of shiny new toys. Explore broadly to dip your toes in a lot of topics, and get deep knowledge of some.
Photo by Annie Spratt
Identify which areas you want to work on to be an even better software engineer. Use our Product Role Matrix to dig deeper into expectations for your current- and target- role, and to define goals for yourself. Seek guidance from your manager, and for help to attach a timeline. Perhaps they can help you track progress, cheer on you while you work towards your goal, and help you to reserve enough time to get there. We will give you room to work on self-improvement. Claim the time you need, and help yourself, your team and your manager by being transparent about what you need.
Good luck, love and light ❤️
The content in this post is inspired by thousands of hours of conversations with engineers and managers, books and articles. Some of those articles are closely aligned to what you’ll read here, and easy to grasp. I encourage you to read them too if you’d like more details, perspectives and guidance on the topic of seniority.
Three good ones are:
- on seniority in software engineering, by Burak Karakan
- Levels of Seniority, by Kamran Ahmed
- What makes you a senior software engineer anyway?, by Swizec Teller
Oh, one last thing for the non-Otovistas reading this post—We’re hiring! Come join our product team as a designer, engineer or product person. Check out our job listings 🤗