It’s been a full year since starting my first full-time software engineering role after graduating college. Over this period of immense growth and learning, I’ve gained a clearer understanding of what pragmatic engineering looks like at scale. The following summarizes some of the most important lessons I’ve come to understand and apply in my day-to-day work.
programming !== engineering
One of my biggest misconceptions when leaving college and entering industry was believing that programming, at large, is the same as engineering. I also assumed that because my undergraduate degree prepared me well for the former, I would naturally excel at the latter. This proved to be a huge mistake.
I realized quickly that while I had solid programming fundamentals, sometimes even surpassing teammates with more seniority, I had significant skill gaps in other fundamental and equally important parts of the software engineering process. These included:
- Writing and configuring different types of tests (unit tests, integration tests, etc.)
- Building and scaling infrastructure in a controlled and secure manner
- Establishing monitoring mechanisms such as dashboards and alarms for operational integrity
- Engaging with customers for feature refinement and feedback I also came to understand that these were the areas where the more senior engineers on the team were particularly strong.
Emphasis on writing
Maybe this is specific to Amazon’s culture, but there is a tremendous emphasis on effective writing. Being able to clearly communicate technical requirements, trade-offs, and processes through writing allows others to quickly engage in discussions and build a shared understanding of the software.
This became very apparent during my document review meeting, where I proposed a technical design for a new feature. Many reviewers raised concerns about the document’s flow and organization, and others pointed out additional edge cases and customer use cases that should be addressed. It became clear that this level of feedback was necessary, since my document served not only to communicate proposed changes to teammates but also to capture feature-specific context for new team members or external engineers.
Communicate for your audience
Communication, both verbal and written, can be highly multidisciplinary when interacting with stakeholders, managers, and customers. As a result, whenever starting a Slack thread or speaking up during a meeting, I’ve learned to put effort into considering the technical knowledge of my audience and bridging any context gaps that may exist. Doing so helps establish a shared foundation from which productive insights and meaningful discussion can emerge.
Overestimate timelines
Though intuitively it feels ideal to provide accurate time estimates, I’ve found that there is real value in overestimating how long tasks will take. Work that appears straightforward on the surface can quickly grow in complexity as you uncover hidden dependencies, coordinate with other team members or stakeholders, or run into unexpected technical challenges. Building in a buffer has helped me set clearer expectations with my manager and teammates, reduce unnecessary pressure, and ensure that the final deliverable meets the standards we expect.
Overestimating time isn’t about lowering the bar but about planning realistically in an environment where uncertainty is normal. It creates space to validate assumptions, perform thorough testing, and handle unforeseen issues. This approach ultimately leads to more reliable delivery and strengthens trust with those who rely on your work.
Understanding the business context
Oftentimes I would be caught up in the depths of technical decisions and details that I would overlook the intended value of a particular feature I was trying to deliver. While this is still something I’m learning to practice more consistently, I’ve started to understand the importance of occasionally stepping back and considering the broader business context in order to make more informed and impactful technical decisions.
Having clarity around why a feature exists, who it serves, and what success looks like provides direction that purely technical reasoning alone cannot. It helps guide trade-offs, ensures prioritization aligns with customer needs, and avoids unneeded complexity. More importantly, it ensures that the solutions we deliver actually provide measurable value for customers and for the business.
These takeaways don’t capture everything I’ve learned this year, but they highlight the areas that have had the biggest impact on my growth so far. I know my perspective will continue to evolve as I gain more experience, but having a better understanding of what actually matters in day-to-day engineering has already made a noticeable difference in how I approach my work.
I’m looking forward to building on these lessons, picking up new ones, and seeing how my understanding of engineering at scale continues to grow.