Senior Software Engineer

Impact

A Senior Software Engineer typically designs many systems inside a team. He or she acts as a technical mentor within the team to guide other engineers on achieving technical excellence.

How to get there

Coding

At this stage, Senior Software Engineers are expected to have excellent coding skills and to be able to execute independently. Code review will shift from nitpicking to general design of the solution instead.

Specialization

In some organizations, the title of "Full Stack Engineer" is sometimes used to describe a senior software engineer:

A fullstack engineer is any engineer capable of executing the entire process of building an end-to-end web experience.

At the senior level, you are expected to be very good at one side of the stack (backend / frontend) and have some knowledge of the other. Otherwise, you would struggle to design systems that integrate well with the other side of the stack.

Mentoring

Start to provide technical mentoring to your peers, especially the junior ones. You may find yourself becoming frustrated with junior engineers because they are slow. Resist that temptation to "fix" their work. Instead:

  • Guide them through your thinking process when designing a new system.
  • Show them what kind of patterns you might use, and patterns you would avoid.
  • Ask questions that will trigger critical thinking - What if the user do this? What if a malicious user comes along? How will this system look like at 10X? 50X? 100X?

Learn how to Conduct a code review that others will thank you for.

Documentation

As you mentor more and more engineers, you might be repeating yourself for commonly asked questions. Learn How to write technical documentation.

Things you might need to document:

  • Onboarding guide: code setup, running tests, IDE
  • Architecture design along with any RFCs
  • How-to guides for problem solving
  • On-call playbooks so engineers would know what steps to run to troubleshoot / fix things
  • APIs and their usage

Software design

At this level, you would already be comfortable with designing medium-large systems within a team. You should be familiar with the domain that your team is operating in, such that you can make good decisions when it comes to Domain-driven design. Real-life system design and text-book / interview system design can be very different. For real-life system design, not only you need to make sure the system scale under load, but also you need to think about security, compliance, etc. You need to think about cost and how the system fits into your organization’s ecosystem. Thinking about it as a whole is hard. Being able to communicate clearly your design with a Technical Design Document is another important skill.

All engineers accumulate technical debt, but senior software engineers and above are expected to have a good control over their technical debt. You should be very familiar with all these Refactoring patterns. Otherwise, consider picking up this excellent book about Refactoring by Martin Fowler

You would notice structural issues accumulating which doesn't appear to make sense at the current scale. Perhaps sometime in the past, someone had design the system for 100 requests per minute (rpm), but at 10K rpm you face scalability issues that you don't see previously. For example:

  • Synchronous service communication might be direct and simple at low scale, ßut at high scale you may find that some parts of the system work could be offloaded to background workers to work asynchronously. Read this article about Synchronous vs Asynchronous communication patterns.

  • At larger scale, you will be parsing more objects / loading more objects in memory. If your payloads were previously a few MB in size per user, then 10K concurrent users might create OutOfMemory situations for you. In that case, you might want to invest some effort in reducing the size of the payloads / changing the schema / changing the transport protocol, etc.

  • You might be working with external vendors / consuming their APIs. At high scale, your system could completely overload their systems and you would have to design fallback strategies to deal with unresponsive vendors.

  • Design your APIs with 'Laziness' in mind. That's universal in all developers (or all humans).

A lot of these issues are covered in the book about Designing Data-Intensive Applications: The Big Ideas Behind Reliable, Scalable, and Maintainable Systems and this is just the tip of the iceberg when it comes to software design. As you explore more problems and solutions, you might find yourself considering a career as a Staff Engineer where you would advance in the career ladder as a senior individual contributor.

Collaboration

Your team is unlikely to operate independently. Requirements will come from other teams or executions will require collaborate with other teams. Being able to gather and understand requirements from stakeholders is an essential skill to ensure you are solving the right problems. Sometimes, the best solutions require no code. Being able to talk to other teams to provide necessary support for your solution is an even more important skill. This is a deciding factor whether you can deliver your solution or not.

Production Operations

Despite your best efforts in reviewing code / mentoring engineers, some bugs are going to slip through the cracks. You must be prepared for this as a Senior Software Engineer as you will most likely be the primary bug fixer if your peers are not able to identify the problems.

Apply best practices when handling production systems:

Read this book about Site Reliability Engineering in Google as it contains many practical suggestions on how to manage your production systems.

Your Reading List for this page