The Sweet Spot Between Too Much and Too Little
How Senior engineers balance over-engineering and under-engineering
š Hi, this is Akash with this weekās newsletter. I write about leadership in software engineering. Thank you for your readership.
Knowing when to stop optimizing separates senior engineers from the rest. This week, Iām sharing practical lessons I learned by making mistakes. They will help you grow beyond Senior. Hope you enjoy this edition!
When designing a system, do you worry about how long it will stay relevant?
Are you spending weeks optimizing for future scale?
I used to get attached to the lifetime of systems I designed to measure my software engineering quality.
As I tied my success to āno bugsā and āsupports insane scaleā, I spent endless hours optimizing. The immediate consequence became longer development time. For seemingly simple components, Iād spend weeks on design.
Itās important to consider future issues when designing a system. You donāt want to redesign from scratch every year. But, finding the balance separated me from most senior engineers around me.
After making countless mistakes, I share what I have learned to decide when to stop. You can apply this to your projects. Using these tips, you can grow as a senior engineer.
ā Main Takeaways
How to avoid building software for entirely imaginary scenarios
Knowing when to spend more time on optimization
Being aware of premature optimization in code or design reviews
š¤Æ Learnings from Over-Engineering
In 2020, I was working on securing Chrome builds. The problem was exciting and applied to many other Google products. At my level, having an impact outside my organization was beneficial. I started speaking with several teams to understand their problems.
I was trying to solve this issue across the company. What I didnāt anticipate was that this,
The solution needs to work across environments
Made the problem unnecessarily complex and difficult
Invited opinions from a developer group of >5000 engineers
The intention behind this was efficiency. Solving a common problem together is excellent. But I was spending too much time on flexibility. Iād spend time,
Optimizing our systems for latency beyond Chromeās requirements
Abstracting Chrome concepts from the core to make the framework flexible
Developing something that is completely outside what we needed for our use case
All this time, my goal was to deliver it for Chrome. A design document would take more than a quarter to review. After chatting with leadership teams and observing the slow progress, we decided to focus on the immediate problem. We had flexibility in the background, but we decided to prioritize Chrome.
My situation wasnāt unique. As Iāve mentored others over the years, many struggle with this. You can avoid optimizing your systems prematurely by,
Separating āwantsā from āneedsā. When you write your design, clearly separate āmustā and āgood to haveā requirements.
Optimizing the right things. Start by evaluating your systems objectively. I have made the mistake of guessing areas to improve. If you focus on optimizing 20% of your code that contributes to 80% of performance, your efforts will be worth it.
Keep it simple. Elegant solutions are simple. Keeping this in mind will help you pass on over-engineering.
š©¹ Learnings from Under-Engineering
Do you feel the speed and quality of engineering work against each other?
Many times, we find ourselves against unrealistic deadlines. We compromise on the solution to get something out the door. I was in a similar situation in 2022. My goal was to design a system for physical machines, and I did just that. However, while the remaining 60% of the fleet was in the cloud, my solution wouldnāt work.
After a couple of quarters, the assumption that āwe need a solution only for physical machinesā wasnāt true. When I returned to the board, I realized we needed to start from scratch. For context, the scale changed from 10K to 100K (QPS).
Scalability and future-proofing your designs are essential. Otherwise, we will find ourselves working on the same problem for longer. In this case, I ignored an immediate future need that cost me two quarters. It wasnāt the only time. Iāve made this mistake many times, but you donāt have to,
Navigate ālow-hanging fruitsā carefully. Quick wins are attractive and sometimes helpful. But, focusing on them is a sign of under-engineering.
Design, get feedback, and develop. Donāt skip to implementation. Sometimes, reviews take longer, which might make us avoid them. Donāt compromise quality for speed.
Anticipate the next version of requirements. Focusing on the immediate need is critical, but also think about the next version. It will help you design systems with scalability in mind.
āļø Balancing the Scale When Working With Others
The problem of overengineering doesnāt apply to our work. It also affects how we work with others. We need to be careful when reviewing others' code and design.
Those endless threads on unimportant things on a pull request or design review arenāt helping anybody.
Neither of these approaches is the right one. As a senior engineer, I always used to nitpick, thinking it was my responsibility as a mentor. Iād look for potential future problems. That wasnāt the problem. The problem was going a bit too far.
I learned to,
Evaluate the value of feedback. Before sharing my opinions, writing down the āwhyā made a huge difference.
āDoes this design support use case X? Itās going to be important soonā
āCaching at the request level is going to be crucial; we have a tight budget on latencyā
āDo you think we should abstract the implementation details? Module X is where we tend to put all utility methodsā
Make proposals actionable. Including the āhowā when sharing ideas makes it easy for others to evaluate.
āDid we consider race condition? Checkout module X which provides utilities you can useā
āNit: Can you add a brief description for this method? Checkout link A for the style guideā
āMaybe we can break this down further? What do you think about A and B?ā
Context matters. When working with other teams, checking their goals and priorities is important. Optimization isnāt going to help during a production outage.
š š Parting Thoughts
Every engineer needs help balancing over-optimization and under-consideration. Thereās no right way to do it, but it is important to understand the trade-offs when making these choices. We covered two scenarios out of my countless mistakes. The trick is to understand the context and ask the right questions.
You can apply them at work to find the sweet spot. A good balance will help you grow much faster in your career.
How do you avoid overdoing it or cutting corners? Share them in the comments!
š¦āš„ This Weekās Favorites
Secrets behind newsletter success from
byHow to build high-performing teams from
byScale to 2.5B users with MySQL from
byIgnoring security alerts (I know, right?) from
by
š š¬ Get In Touch
Want to chat? Find me on LinkedIn.
If you want me to cover a particular area of leadership, you can reach out directly to akash@chromium.org.Ā
If you enjoyed this content, please š share it with friends and consider š subscribing if you havenāt already. Your š response really motivates me to keep going.
Explain in excellent way
Nice article! Something similar happened to me in the last few years.
In my case, I also struggled with stakeholders' expectations. Trying to set clear boundaries to what were the expectations for the solution helped me to find a balance of what I had to do in some situations. But, it is not as easy as it sounds.
Thanks for the article!