Becoming a High-Performance Software Engineer

Itay Waxman
Riskified Tech

--

What does it take to become a high-performance engineer in a fast-growing organization? The motivation for excelling in your work might sound obvious: the better your performance and impact, the higher your reward, personal growth, and sense of fulfillment. But knowing how to get there is another matter.

As a software engineer turned engineering manager within Riskified, I can provide a multifaceted perspective on which behaviors and actions are most beneficial. In my opinion, an engineer’s day-to-day work — merging code to the project’s repository, following your team’s coding standards, debugging issues and delivering on-time — is an expected bar from all software engineers. To stand out and create a major impact requires more. I believe that, at their core, such an engineer is someone who aims for excellence and to create an impact beyond their own individual work.

In this blog post, I’ll highlight important yet less commonplace proposals and guidelines that should produce high performance that will get you constant personal growth, good feedback, and maybe even a raise or a promotion.

Be engaged in meetings

Before any engineering solution is decided and go into a development phase, there are planning meetings that should provide the business context and requirements. You should be an engaged and active participant in these discussions. In order to master your team’s domain, you must ask questions, refine the requirements, and have a clear understanding of what you are planning to build and how it advances the team’s mission.

At Riskified, for example, we aim to build teams around one product or mission, and our development team works closely with a dedicated product manager. Once, as we were planning a big feature and still deep into the how and where we needed to make changes to our codebase, an engineer insisted on additional clarification about how many users were expected to reach this phase. Our product manager provided us with the exact numbers, and we were able to show the effort was not worth the value, allowing us to better allocate our resources elsewhere.

Planning meetings are just one kind of meeting. I would encourage you to find interest and be passionate about any meeting. Make the best of the time spent. Be present. Come prepared to meetings and make sure you understand the meeting’s objective and what knowledge to collect beforehand. As time goes on, you’ll see the team start to rely on your insights and opinions — this is impact.

Be Independent and able to raise flags effectively

Being independent gains you trust from your manager and team and opens opportunities for you to take the lead in bigger features. An independent engineer should be able to balance individual work and with assistance from colleagues. But what is the correct balance? Well, I think it means that most of the time you can provide value on your own — completing a task or a feature end to end. When you can’t, you are expected to be responsible enough to ask for the help you need.

A basic guideline for taking a feature E2E (end-to-end) is to first make sure you understand all the requirements, business context, and who the stakeholders are. After that, before diving into coding, take some time to plan how this feature is going to be built, which code repos will be involved, how the parts will come together, and how you will verify it works.

As your task is in progress, there will occasionally be issues that block you from proceeding, such as “code doesn’t compile” or “missing permission for S3 bucket.” If several attempts to resolve it on your own don’t get the job done, it’s time to ask for assistance.

You should be methodologic about it:

1. Pinpoint the most suitable person to assist

2. Prepare all the information that will allow your assistant a quick entry:

  • What you’re trying to do
  • What’s preventing you from succeeding
  • What troubleshooting steps you performed so far

3. Notify stakeholders if needed (if delivery is going to be delayed or unplanned extra work is needed)

Since you’ll ask for help only after you’ve made a major effort to resolve it on your own and followed the instructions above, you’ll achieve:

  • A good reputation for asking for assistance only when really needed
  • Less inefficient conversions (‘ping pong’) — hopefully resulting in a faster resolution
  • Reduced miscommunication with stakeholders

Close all loops

Be a true feature owner. When working on a task, you should constantly check that nothing falls between the cracks. If the task’s ticket is missing some details, make sure the missing information is written. Create story tickets when discovering important out-of-scope parts and make sure they’re backlogged. If, for example, you find that an API you’re adjusting is receiving requests that should be sanitized — it might be a lower priority for now, but it is still important to handle at some point. Don’t skip testing every scenario of your feature. Whether it’s manual or automated — do it. When you move your task to Done, you should be 100% sure it has met all its definitions of done.

Following this advice will gain you the trust of your manager, team, and other stakeholders. They’ll be confident you’re on top of things.

Conduct micro-refactors

There’s a saying in the Boy Scouts: “always leave the campground cleaner than you found it.” It means that when we make a change to a code area, we leave it in a better state than how we found it (even if we’re not the ones who left all those Magic Numbers). When I decided to title this section “micro-refactors,” I was explicitly not referring to conducting regular code refactors, which are also a good habit to have but should be planned in advance. When it comes to small or micro-refactors, they should be performed constantly and so as to not delay our feature delivery time. Extract classes or methods to make the code more maintainable, remove redundant comments or unused code, fix typos, etc. In other words, align the areas of code you touch to high coding standards. It doesn’t take too much time, and eventually you’ll be doing it automatically.

As a manager, when I see engineers who take the time to do that, I know that they care about our code base and are actively trying to improve what we’ve right now. A better code base is something any team should aim for, but it won’t happen all of a sudden for the existing codebase — small but consistent step by step improvements are a better approach.

Have production on your mind

A stable and working production should always be the top priority for a development team. As an engineer in a team, you should incorporate the habit of checking your alerts and monitoring dashboards into your daily routine. Though you would expect critical issues to be triggered as an alert on push, there might be issues that are not yet covered by an alert and can only be noticed through monitoring dashboards or low-urgency alerts that go to Slack channels. This kind of mentality will help catch bugs and issues before they have a major impact. Also, when incidents happen in your team, be proactive and join the investigation and resolution efforts.

You can be sure that your team and management appreciate your efforts to prevent and resolve such incidents.

Once this mentality is in effect, you’ll be more aware of what metrics are important to monitor.

This will allow you to effectively:

  • Create the right alerts when you develop and toggle-on features in production
  • Create and update your monitoring dashboards to allow efficient troubleshooting
  • Pinpoint low-urgency error-based alerts that need be transformed into ratio metric-based alerts as high-urgency alerts (usually needed when one error is nothing to worry about but 1,000 errors are)
  • Have a better understanding of what’s the right alert thresholds

Always learn

In the field of software development, technology and best practices never stop evolving. To stay relevant and excel, a high-performing engineer should always be passionate about learning and broadening his or her knowledge. Take the extra time to do it (even outside of “working hours”). Find opportunities during your day-to-day work, meetings, and hallway chat to create a bucket list of learning subjects. For example, if your team started to work with a new database, read about its advantages vs. disadvantages, common use-cases, and even check all the available clients in your coding language. When you’re not familiar with something that came up in a meeting, be sure to follow up on it in your own time (When a buzzword is dropped, google it and come prepared next time). This can also be applied to information you’re missing concerning the product you’re working on — you should learn all its aspects and become a master of your own domain.

Once you find a learning subject, a good way to become proficient and learn effectively is to use the 70–20–10 learning model. In short, it’s how much percentage of time you allocate to each learning platform:

  • 70% to on the job training
  • 20% to peer learning
  • 10% to the theoretical material

You’ll still need to think ahead and decide how you are going to fulfill each of the above. For example, if you want to improve your architecture engineering skills:

  • On the job training — you can ask for a big feature that requires such planning
  • Peer learning — ask a software architect or another senior engineer to review your plans
  • Theoretical material — the internet is your friend (online courses, lectures, podcasts, blogs, etc)

Help your team members

Being available and approachable to assist your teammates will allow your team to be confident that they have someone who will back them up, create a collaborative environment, and ultimately make the team run faster. As a manager, my goal is to make the sum of the team bigger than the sum of its parts. Therefore, I appreciate and value engineers who are team players. It’s old thinking that the team manager is the sole point of contact for raising issues — be the person the team can count on.

Making the context switch from what you’re working on to help your teammates when they’re blocked or requesting a code review should be something you’re doing constantly. When I’m coding, I take focused coding sessions of an hour and a half and between them I always check whether anyone needs something. When someone is waiting for a code review, being attentive will accelerate their delivery time. If there’s a technical issue someone is facing, another fresh set of eyes can help find a solution from a different angle.

Listen to your managers

I mean, really listen. Your managers probably state what’s important to them or the organization (if it’s not clear — ask). You should always try and find opportunities to contribute to the focus areas being talked about. It could be that your manager is really trying to put an emphasis on making sure every feature is covered by automated tests (since you’ve had too many production incidents lately), or that the organization is growing and hiring became the highest priority (since your company wants to double your headcount).

So, double-check your feature tests are well-written. Volunteer to help with hiring — maybe there’s a need for new interview questions you can write, or maybe you can mentor new interviewers or write a blog post with a link to your career page (yes, we’re hiring!).

There’s a reason your managers say what they say — aligning the entire development team with the bigger picture. By promoting your manager’s cause, you make a big impact (contributing where it’s important) and gain positive credit and appreciation from your manager on the way.

Be positive with a can-do attitude

By a positive mindset I mean try to mostly see the good in people, don’t be cynical, and work with less ego. It’ll allow you to get along with your colleagues better and be more approachable.

Since everyone likes to work with people who are pleasant and patient with them, it’ll be easier to offer new opportunities to such people. Think about it: if someone is going to ask you to work on a new feature that involves new coding languages and you’ll reply with negative comments (“JavaScript??? I’d rather parse JSONs manually”), you might not only miss this and future opportunities but also harm your relationship with that person (he might really like JavaScript).

So this is where the can-do attitude comes in. When presented with a request or task that is out of your comfort zone, try to be open about it. It could be a task that involves a technology you’re not familiar with or just a request to present something to a large forum. This is the way to grow but also displays openness — it’ll allow your manager to offer you with more opportunities in the future.

Ask for feedback

You should strive for ongoing feedback from your manager and peers. Ask for it in the one-on-one with your manager, when finishing a coding pairing session with a colleague, etc.

This is the best way to improve and receive validation that your self-perception and the way other people see you are aligned.

I would also recommend writing a yearly self-feedback. It’ll help you to honestly realize where you see yourself and what were your biggest achievements in the past year.

Conclusion

All the behaviors and habits discussed above can be endorsed by any engineer (at any experience level). They require mostly awareness and a mentality change. Applying them creates an impact outside the boundaries of the individual work and displays strong professional capabilities. I believe these blog post suggestions offer solid foundations to become a high-performance software engineer. Of course, they only touch on part of the picture; there’s always room for more personal growth and improvement.

--

--