<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Effective Engineering @ effective-engineer.com]]></title><description><![CDATA[Supporting you in becoming a better Software engineer. ]]></description><link>https://www.effective-engineer.com</link><image><url>https://substackcdn.com/image/fetch/$s_!RHVg!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5324142-ea10-4cab-94b3-ccaff1a48205_608x608.png</url><title>Effective Engineering @ effective-engineer.com</title><link>https://www.effective-engineer.com</link></image><generator>Substack</generator><lastBuildDate>Wed, 06 May 2026 10:33:34 GMT</lastBuildDate><atom:link href="https://www.effective-engineer.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[The effective engineer]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[theeffectiveengineer@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[theeffectiveengineer@substack.com]]></itunes:email><itunes:name><![CDATA[Effective Engineering]]></itunes:name></itunes:owner><itunes:author><![CDATA[Effective Engineering]]></itunes:author><googleplay:owner><![CDATA[theeffectiveengineer@substack.com]]></googleplay:owner><googleplay:email><![CDATA[theeffectiveengineer@substack.com]]></googleplay:email><googleplay:author><![CDATA[Effective Engineering]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[14 Steps to a Winning Start in Your New Role]]></title><description><![CDATA[Kickstart your new job with a plan !]]></description><link>https://www.effective-engineer.com/p/14-steps-to-a-winning-start-in-your</link><guid isPermaLink="false">https://www.effective-engineer.com/p/14-steps-to-a-winning-start-in-your</guid><dc:creator><![CDATA[Effective Engineering]]></dc:creator><pubDate>Fri, 10 Jan 2025 16:14:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!_ucu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d171230-1f21-46dd-acbb-8384c83eca79_1400x933.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Starting a new tech role can feel like jumping into the deep end of the pool. You&#8217;re excited, but there&#8217;s a lot to take in. From understanding your team&#8217;s tech stack to learning the codebase, onboarding is about finding your rhythm while contributing to meaningful work. </p><p>The best part? </p><p>With the right approach, you can set yourself up for success and integrate into your new role while making great first impressions.</p><p>We will go over a 14-step plan that will help you ensure a smooth onboarding and that you&#8217;re set for success in your new job.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_ucu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d171230-1f21-46dd-acbb-8384c83eca79_1400x933.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_ucu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d171230-1f21-46dd-acbb-8384c83eca79_1400x933.jpeg 424w, https://substackcdn.com/image/fetch/$s_!_ucu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d171230-1f21-46dd-acbb-8384c83eca79_1400x933.jpeg 848w, https://substackcdn.com/image/fetch/$s_!_ucu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d171230-1f21-46dd-acbb-8384c83eca79_1400x933.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!_ucu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d171230-1f21-46dd-acbb-8384c83eca79_1400x933.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_ucu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d171230-1f21-46dd-acbb-8384c83eca79_1400x933.jpeg" width="1400" height="933" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0d171230-1f21-46dd-acbb-8384c83eca79_1400x933.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:933,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!_ucu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d171230-1f21-46dd-acbb-8384c83eca79_1400x933.jpeg 424w, https://substackcdn.com/image/fetch/$s_!_ucu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d171230-1f21-46dd-acbb-8384c83eca79_1400x933.jpeg 848w, https://substackcdn.com/image/fetch/$s_!_ucu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d171230-1f21-46dd-acbb-8384c83eca79_1400x933.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!_ucu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d171230-1f21-46dd-acbb-8384c83eca79_1400x933.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>1. Clarify Your Role and Expectations Early</strong></h2><p>When you first start, it&#8217;s easy to get overwhelmed by new tools, workflows, and processes. But without clarity about what&#8217;s expected of you, it&#8217;s hard to sense if you&#8217;re heading in the right direction. </p><p>The best thing you can do early on is sit down with your manager and ask directly about the key goals for your role. This isn&#8217;t just about knowing what tasks you&#8217;ll be tackling but understanding the larger context of how your work fits into the company&#8217;s vision. </p><p>By aligning yourself with the broader mission, you&#8217;ll ensure that you&#8217;re adding value from the start and clearly understand what success looks like.</p><h2><strong>2. Get Comfortable with the Tech Stack and Tools</strong></h2><p>A new job can sometimes feel like an endless sea of tools and technologies to learn. Whether it&#8217;s a new programming language, a framework, or an internal tool, each piece plays a critical role in your daily workflow. The key here is to focus on getting comfortable, not mastering everything at once. Start by familiarizing yourself with debugging tools and the team&#8217;s daily-use tools. </p><p>As you go deeper, you&#8217;ll naturally identify areas that require more focus, but starting with a broad understanding will help you hit the ground running.</p><h2><strong>3. Absorb the Codebase Like a Sponge</strong></h2><p>Understanding the codebase is crucial for your long-term success. At first, it might feel overwhelming, especially if the codebase is vast or complex. Start by exploring the key modules and understanding how data flows through the system. Look at how the app handles requests, processes data, and communicates with external services. Instead of just reading through the code, try to visualize the structure. Over time, you&#8217;ll better understand the code&#8217;s architecture and how each part fits together.</p><h2><strong>4. Dive into Onboarding Documentation</strong></h2><p>Most companies provide some form of onboarding documentation, and it can be tempting to skim through it, especially when you&#8217;re eager to jump into the action. Spending time with these materials can save you hours of confusion later. </p><p>From company policies to technical workflows, onboarding docs are your go-to reference for understanding the company&#8217;s expectations and practices. Highlight important points, and jot down questions.</p><h2>5. Build Relationships with Your Team</h2><p>Tech is a collaborative field, and your success as an engineer is often tied to the relationships you build. Get to know your teammates, not just as co-workers but as people. Understanding their strengths, communication styles, and work habits will make it easier to collaborate. These initial relationships provide a support network when things get challenging, helping you navigate the tech culture and beyond.</p><h1><strong>6. Understand the Product Deeply</strong></h1><p>While diving into the technical side of things, don&#8217;t forget to get acquainted with the product you&#8217;re building. Take time to use the product as an end-user. Understanding the problems the product is solving gives you a solid foundation to make decisions that directly impact users. The product is more than just code; it&#8217;s what makes your technical efforts meaningful.</p><h2><strong>7. Get Familiar with Development Workflows</strong></h2><p>Each team has its approach to work. Whether you&#8217;re using Scrum, Kanban, or some hybrid model, understanding your team&#8217;s development workflows is essential. Get familiar with how the work is organized, and how tasks are assigned, tracked, and reviewed. Knowing how things move from one stage to another helps you understand where your contributions fit in.</p><h2><strong>8. Learn the Testing and CI/CD Pipelines</strong></h2><p>Tech is all about quality, and quality comes from great testing and continuous integration. Early in your journey, understanding how the team tests code and manages releases is invaluable. By aligning with these practices early, you&#8217;ll avoid unnecessary headaches down the road and contribute reliable code to production.</p><h2><strong>9. Participate in Code Reviews</strong></h2><p>Code reviews are one of the most effective ways to learn and improve. Observe how your colleagues approach different problems, structure their code, and follow patterns. Contribute feedback on other people&#8217;s PRs to develop a critical eye for good code. When it&#8217;s time for your code to be reviewed, be open to feedback and use it as a chance to grow.</p><h2><strong>10. Understand the Deployment Process</strong></h2><p>Knowing how your team deploys software to production is crucial. Understand the deployment pipeline, how rollbacks are handled, and what post-deployment monitoring looks like. Familiarizing yourself with these processes early on will make you confident about pushing code live and prepared to handle any issues that arise.</p><h2><strong>11. Ask Questions, Even the Obvious Ones</strong></h2><p>No one expects you to know everything right away. Asking questions shows you&#8217;re engaged and committed to doing your job well. Don&#8217;t hesitate to clarify anything that seems unclear; curiosity is a sign of dedication.</p><h2><strong>12. Tackle Small Wins Early</strong></h2><p>Look for smaller tasks you can complete to build momentum. Whether it&#8217;s fixing a bug, refining a piece of code, or improving documentation, these small wins will help you gain confidence and establish your place in the team.</p><h2><strong>13. Document What You Learn</strong></h2><p>As you learn new concepts, internal tools, and team practices, create your reference library. Over time, this becomes an invaluable resource for your growth and helps you onboard future colleagues more effectively.</p><h2><strong>14. Network Beyond Your Team</strong></h2><p>To thrive, you need to collaborate across teams. Connect with people from different areas of the company to build cross-functional relationships. This broader perspective will help you see the bigger picture and make your work more impactful.</p><h2><strong>Make the Most of Your Onboarding Journey</strong></h2><p>Onboarding is your launchpad in a new role, and how you approach it can shape your entire experience. Stay proactive, ask questions, and keep learning. Success doesn&#8217;t come from just showing up; it comes from actively shaping your path forward.</p><p><em><strong>&#128073; <a href="http://www.effective-engineer.com/">Checkout my blog</a><br>&#128038; <a href="https://x.com/EffectiveEng">Follow me on X</a></strong></em></p>]]></content:encoded></item><item><title><![CDATA[Resilient Systems: Lessons for Startup Engineers]]></title><description><![CDATA[Master Software Reliability Engineering for startups. Learn to build resilient systems with observability, incident management, scaling, and best practices]]></description><link>https://www.effective-engineer.com/p/resilient-systems-lessons-for-startup</link><guid isPermaLink="false">https://www.effective-engineer.com/p/resilient-systems-lessons-for-startup</guid><dc:creator><![CDATA[Effective Engineering]]></dc:creator><pubDate>Fri, 03 Jan 2025 20:42:25 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!s8mX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ff1f89d-4fa4-4850-9858-eccc7271d845_1400x933.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!s8mX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ff1f89d-4fa4-4850-9858-eccc7271d845_1400x933.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!s8mX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ff1f89d-4fa4-4850-9858-eccc7271d845_1400x933.jpeg 424w, https://substackcdn.com/image/fetch/$s_!s8mX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ff1f89d-4fa4-4850-9858-eccc7271d845_1400x933.jpeg 848w, https://substackcdn.com/image/fetch/$s_!s8mX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ff1f89d-4fa4-4850-9858-eccc7271d845_1400x933.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!s8mX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ff1f89d-4fa4-4850-9858-eccc7271d845_1400x933.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!s8mX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ff1f89d-4fa4-4850-9858-eccc7271d845_1400x933.jpeg" width="1400" height="933" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0ff1f89d-4fa4-4850-9858-eccc7271d845_1400x933.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:933,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!s8mX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ff1f89d-4fa4-4850-9858-eccc7271d845_1400x933.jpeg 424w, https://substackcdn.com/image/fetch/$s_!s8mX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ff1f89d-4fa4-4850-9858-eccc7271d845_1400x933.jpeg 848w, https://substackcdn.com/image/fetch/$s_!s8mX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ff1f89d-4fa4-4850-9858-eccc7271d845_1400x933.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!s8mX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0ff1f89d-4fa4-4850-9858-eccc7271d845_1400x933.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@dropthelabelmovement?utm_source=medium&amp;utm_medium=referral">Drop the Label Movement</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure></div><p>Every engineer should know how to build resilient systems. I learned this In the several fast-paced startup environments I worked at, where rapid iterations, shifting priorities, and limited resources are the day-to-day norm.</p><p>In startups, Growth and learning opportunities are huge, but this comes at the cost of having to wear multiple hats. Launching new features and growing the product are essential, but what determines the success or failure of a feature is system resilience. Without it, features will be a customer&#8217;s pain point rather than an added value. This can cost users, reputation, and even cripple the business.</p><p>In this article, We will explore what every engineer needs to know about Software Reliability Engineering (SRE).</p><h2><strong>Resilience Starts with the Engineer</strong></h2><p>Resilience is the ability of a system to recover from failure, and it&#8217;s a responsibility shared by every engineer, no matter their role or company size. Every decision, from design to deployment, impacts system reliability. Engineers must build systems that can handle failures gracefully.</p><p>Imagine facing a sudden traffic surge due to a marketing campaign. A third-party API integration begins to timeout, causing some functionality to fail. This leads to wasted marketing efforts, a poor user experience, and I am pretty sure it will cause an increase in bounce rates and a decrease in retention for first time customers.</p><p>If caching or a backup integration were implemented, we could have avoided these issues. This highlights the importance of designing for failure and how it ensures system resilience in the face of unexpected challenges.With resilience in mind, the next step is ensuring we have full visibility into the health of our systems.</p><h2><strong>Observability is all you need</strong></h2><p>Having comprehensive visibility into your system&#8217;s health is critical for early issue detection and prevention. Without proper monitoring, it&#8217;s easy to miss performance problems that can lead to downtime, and lost revenue. The sooner you can identify issues, the faster you can handle them before they escalate into bigger failures that affect the business.</p><p>In my experience, focusing on a few core metrics like response times, error rates, and uptime provides a clear, actionable view of system performance. By measuring these metrics, you get the visibility needed to understand how your system is performing and where to focus your attention.</p><p><strong>Tools for Observability:</strong></p><p><strong>Log Management and Analysis </strong>OpenSearch and ELK Stack (Elasticsearch, Logstash, Kibana) help track and analyze system events, enabling deep insights into system behavior.</p><p><strong>Performance Monitoring: </strong>Datadog, New Relic, and Prometheus provide comprehensive performance monitoring, tracking infrastructure health, application performance, and user interactions.</p><p><strong>Visualization and Dashboards: </strong>Grafana offers real-time dashboards for visualizing system health, often used with Prometheus.</p><p><strong>Edge and Deployment Monitoring:</strong>Cloudflare ensures optimal performance during high traffic, and Argo offers real-time visibility into deployment pipelines.</p><p><strong>Incident Management and Alerting: </strong>PagerDuty provides real-time alerts and escalations, helping teams act swiftly during incidents.</p><p>These tools offers you the end-to-end visibility needed to have a faster issue resolution and a more reliable system. But we can&#8217;t prevent incidents, eventually one will catch us off guard.</p><h2><strong>Prepare to crash</strong></h2><p>Incidents will happen, it is just a matter of when, therefore incident management is important for maintaining system reliability.</p><p>One way we can prepare is by setting up a <strong>runbook</strong> in advance. A runbook is a guide that includes common issues, resolution steps, escalation procedures, and how to go back to normal operations.It helps ensure consistency, decreases mean time to recovery, and enables teams to handle incidents effectively and minimize downtime.</p><p>One other we can use to prepare is conducting regular &#8220;fire drills,&#8221; inspired by Netflix&#8217;s Chaos Engineering, where issues are introduced as a test to identify gaps and improve response capabilities.</p><h2><strong>Scaling Early and Often</strong></h2><p>Scaling should be considered from the start. Expecting growth, and peak traffic helps you build systems that scale as demands increase.</p><p>Stress-test your systems to uncover performance bottlenecks before real traffic hits, ensuring you optimize ahead of time. Design for resilience by focusing on core features and providing fallback options to minimize user impact during failures.</p><p>Lastly, be effective by avoiding overscaling and make sure to match resources to actual demand.</p><h2><strong>Building Resilience One Engineer at a Time</strong></h2><p>Every engineer has a role in making the system resilient. By preparing for failure, monitoring the system, handling incidents effectively, and learning from mistakes, we can ensure long-term growth and reliability.</p><p><em><strong>&#128073; <a href="http://www.effective-engineer.com/">Checkout my blog</a><br>&#128038; <a href="https://x.com/EffectiveEng">Follow me on X</a></strong></em></p>]]></content:encoded></item><item><title><![CDATA[Scaling Twitter: How Addressing Technical Debt Rescued the Platform]]></title><description><![CDATA[Learn how technical debt can sink companies and discover strategies to identify, prioritize, and tackle debt for building resilient systems and sustainable growth.]]></description><link>https://www.effective-engineer.com/p/scaling-twitter-how-addressing-technical</link><guid isPermaLink="false">https://www.effective-engineer.com/p/scaling-twitter-how-addressing-technical</guid><dc:creator><![CDATA[Effective Engineering]]></dc:creator><pubDate>Thu, 02 Jan 2025 12:11:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!OTbY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca4852c-71cd-4bd7-bfe3-25afe37245ad_743x631.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!OTbY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca4852c-71cd-4bd7-bfe3-25afe37245ad_743x631.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OTbY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca4852c-71cd-4bd7-bfe3-25afe37245ad_743x631.png 424w, https://substackcdn.com/image/fetch/$s_!OTbY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca4852c-71cd-4bd7-bfe3-25afe37245ad_743x631.png 848w, https://substackcdn.com/image/fetch/$s_!OTbY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca4852c-71cd-4bd7-bfe3-25afe37245ad_743x631.png 1272w, https://substackcdn.com/image/fetch/$s_!OTbY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca4852c-71cd-4bd7-bfe3-25afe37245ad_743x631.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!OTbY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca4852c-71cd-4bd7-bfe3-25afe37245ad_743x631.png" width="743" height="631" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5ca4852c-71cd-4bd7-bfe3-25afe37245ad_743x631.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:631,&quot;width&quot;:743,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!OTbY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca4852c-71cd-4bd7-bfe3-25afe37245ad_743x631.png 424w, https://substackcdn.com/image/fetch/$s_!OTbY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca4852c-71cd-4bd7-bfe3-25afe37245ad_743x631.png 848w, https://substackcdn.com/image/fetch/$s_!OTbY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca4852c-71cd-4bd7-bfe3-25afe37245ad_743x631.png 1272w, https://substackcdn.com/image/fetch/$s_!OTbY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ca4852c-71cd-4bd7-bfe3-25afe37245ad_743x631.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>In the early 2010s, Twitter became viral for real time news, and they acquired a lot more customers. The company was succeeding in the social media scene and became the talk in the tech scene. But Twitter was battling a silent threat: <strong>technical debt.</strong></p><p>In this article we will explore Twitter&#8217;s &#8220;Fail Whale&#8221; and how technical debt can cripple even the most promising companies. We will discuss how to identify, prioritize, and tackle technical debt before it spirals out of control.</p><h4>Origins of Technical Debt</h4><p>We often take shortcuts to meet the demanding timelines, creating technical debt. Like financial debt, it accumulates interest over time. Growing from what started as a quick fix into a bigger issue if not addressed.</p><blockquote><p><em>&#8220;Shipping first time code is like going into debt. A little debt speeds development so long as it is paid back promptly with a rewrite or refactor. The danger comes when debt is allowed to accumulate and is not paid back.&#8221;<br>- </em><strong>Ward Cunningham</strong>, The person who coined the term</p></blockquote><p>In Twitter&#8217;s case, this debt was the result of rapid feature development, shortcuts taken to meet user demands, and an architecture that couldn&#8217;t keep up with the platform&#8217;s growth.</p><h4><strong>The Rise of the Fail Whale</strong></h4><p>In its early days, Twitter&#8217;s system couldn&#8217;t handle the unexpected, rapid growth. This led to frequent outages and made feature additions and bug fixes slow and risky, while engineers were stuck in a firefighting mode, focused on maintaining stability rather than improving the platform. Twitter accumulated a lot of interest which created a culture dominated by technical debt, and damaged morale.</p><h4>The Cost of Ignoring Technical Debt</h4><p>Technical debt is often looked at as a technical issue and dealing with it can be doomed as an unaffordable luxury but it&#8217;s a risk that could break the business. For Twitter, the Fail Whale wasn&#8217;t just an inconvenience; it was a brand problem.</p><ol><li><p><strong>User Frustration</strong>: users began to lose trust in the platform. Frustrated by the unreliable service, some stopped using Twitter altogether.</p></li><li><p><strong>Reputational Damage</strong>: The Fail Whale started as a fun mascot, but it soon became a public reminder of the platform&#8217;s technical struggles.</p></li><li><p><strong>Slower Innovation</strong>: With engineers tied up in maintaining the system, features took longer to ship</p></li></ol><p>As the Fail Whale became a clear threat to Twitter&#8217;s future, leadership realized the importance of addressing technical debt.</p><h4>How to Deal with Technical Debt: Lessons Learned</h4><p>Twitter&#8217;s experience offers key lessons for managing technical debt. Below are practical steps your team can adopt:</p><h4><em>1. </em>Identifying Technical Debt</h4><ul><li><p><strong>Codebase Reviews</strong>: Regularly audit your codebase to identify areas of complexity or fragile components.</p></li><li><p><strong>Tracking Debt</strong>: Use static analysis tools to track cyclomatic complexity and duplication.</p></li><li><p><strong>Continuous Monitoring</strong>: Use monitoring tools like Datadog or New Relic to track Mean Time to Recovery.</p></li></ul><h4>2. Prioritizing Debt Payoff</h4><ul><li><p><strong>Risk Assessment</strong>: Prioritize debt based on its potential impact on system performance and team productivity.</p></li><li><p><strong>Debt Register</strong>: Maintain a backlog of debt items and prioritize by severity and business needs. I have a monthly <a href="https://en.m.wikipedia.org/wiki/Team_programming#Mob_programming">MOB</a> session with the team to pair on these.</p></li><li><p><strong>Low-Hanging Fruit</strong>: Tackle small, high-impact issues that can be quickly resolved to build momentum.</p></li></ul><h4>3. Incorporating Debt Management into Workflow</h4><ul><li><p><strong>Debt Allocation in Sprints</strong>: Dedicate a percentage (e.g., 10%) of each sprint to refactoring or resolving debt.</p></li><li><p><strong>Continuous Refactoring Policy</strong>: Clean up code whenever modifying functionality to prevent future debt.</p></li></ul><h4>4. Long-Term Prevention Strategies</h4><ul><li><p><strong>Code Reviews</strong>: Implement thorough reviews to catch shortcuts and promote the refactoring policy.</p></li><li><p><strong>Architectural Planning</strong>: Regularly revisit architectural decisions to ensure it aligns with evolving business needs.</p></li></ul><h4>5. Communication and Stakeholder Alignment</h4><ul><li><p><strong>Cost-Benefit Analysis</strong>: Quantify the trade-offs between addressing debt and delivering features to align with business priorities.</p></li><li><p><strong>Narrative Framing</strong>: Use stories like the Fail Whale to convey the impact of unchecked debt to non-technical stakeholders.</p></li><li><p><strong>Advocate for Budget</strong>: Build a business case for dedicated resources to manage and reduce technical debt.</p></li></ul><h4>The Outcome: From Fail Whale to Resilience</h4><p>technical debt can&#8217;t be prevented. But with the right strategies, it can be paid off. I have always considered twitter journey as a reminder of the impact technical debt has on a business. Make sure to consistently pay off technical debt to streamline shipping and avoid fixing.</p><p><em><strong>Support me by subscribing here and following me on X</strong>  </em></p><p><em><strong>&#128073; <a href="http://www.effective-engineer.com/">Checkout my blog</a><br>&#128038; <a href="https://x.com/EffectiveEng">Follow me on X</a></strong></em></p>]]></content:encoded></item><item><title><![CDATA[Effective Refactoring: Balancing Principles and Practicality]]></title><description><![CDATA[how principles can sometimes lead to unnecessary complexity in your code. Discover when it's better to prioritize simplicity and clarity.]]></description><link>https://www.effective-engineer.com/p/effective-refactoring-balancing-principles</link><guid isPermaLink="false">https://www.effective-engineer.com/p/effective-refactoring-balancing-principles</guid><dc:creator><![CDATA[Effective Engineering]]></dc:creator><pubDate>Wed, 01 Jan 2025 08:08:10 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!46B6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9436b334-f227-45ea-b536-dfd5db9ce39b_1400x933.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!46B6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9436b334-f227-45ea-b536-dfd5db9ce39b_1400x933.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!46B6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9436b334-f227-45ea-b536-dfd5db9ce39b_1400x933.jpeg 424w, https://substackcdn.com/image/fetch/$s_!46B6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9436b334-f227-45ea-b536-dfd5db9ce39b_1400x933.jpeg 848w, https://substackcdn.com/image/fetch/$s_!46B6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9436b334-f227-45ea-b536-dfd5db9ce39b_1400x933.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!46B6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9436b334-f227-45ea-b536-dfd5db9ce39b_1400x933.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!46B6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9436b334-f227-45ea-b536-dfd5db9ce39b_1400x933.jpeg" width="1400" height="933" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9436b334-f227-45ea-b536-dfd5db9ce39b_1400x933.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:933,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!46B6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9436b334-f227-45ea-b536-dfd5db9ce39b_1400x933.jpeg 424w, https://substackcdn.com/image/fetch/$s_!46B6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9436b334-f227-45ea-b536-dfd5db9ce39b_1400x933.jpeg 848w, https://substackcdn.com/image/fetch/$s_!46B6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9436b334-f227-45ea-b536-dfd5db9ce39b_1400x933.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!46B6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9436b334-f227-45ea-b536-dfd5db9ce39b_1400x933.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>The reality of a developer&#8217;s day-to-day work doesn&#8217;t leave room for perfectionism. Refactoring is essential for maintaining healthy codebases as It ensures that software remains maintainable, scalable, and resilient to future changes. But in the real world, developers often deal with tight deadlines, business goals, and legacy systems.</p><p>Martin Fowler defines refactoring as :</p><blockquote><p><em><strong>The process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure.</strong></em></p></blockquote><p>When done correctly, refactoring:</p><ul><li><p><strong>Improves readability:</strong> Makes the code easier to understand.</p></li><li><p><strong>Enhances maintainability:</strong> Simplifies future changes and debugging.</p></li><li><p><strong>Reduces technical debt:</strong> Prevents long-term costs by addressing issues early.</p></li></ul><p>In this article we will explore how to approach refactoring effectively and realistically, balancing principles like DRY (Don&#8217;t Repeat Yourself) and SOLID with the realities of our day to day, but let&#8217;s first explore how to identify the code that needs us to invest time in.</p><h2><strong>How to Identify Code That Needs Refactoring</strong></h2><p>I once inherited an e-commerce system from an outsourcing company that was terminated due to system quality issues. The main issues were that items frequently went vanished from the inventory, quantities were updating randomly and whenever a patch was made, some thing else broke.</p><p>I have dealt with a lot of similar cases to learn that this is a sign to refactor. The signals that I use to determine that are:</p><ol><li><p><strong>Frequent Bugs in same module:</strong> If the same module repeatedly causes issues, it&#8217;s a candidate for refactoring.</p></li><li><p><strong>Hard-to-Read Code:</strong> If understanding a function feels like deciphering a riddle, it needs simplification.</p></li><li><p><strong>Slow Development:</strong> Fixing bugs took forever due to high coupling.</p></li><li><p><strong>Duplication:</strong> Functions were cloned everywhere.</p></li><li><p><strong>Code Rot:</strong> Functions or modules with too many responsibilities.</p></li></ol><p>It doesn&#8217;t make sense to strictly follow principles on a huge codebase when things are this bad. We need a balance that will maintaining a rational timeline while following best practices like avoiding duplication.</p><h2><strong>Balancing DRY and Simplicity</strong></h2><p>The DRY principle advocates eliminating duplicate code, but it can lead to over-abstraction. For example, pulling out shared logic into a single function can inadvertently couple unrelated modules. While DRY promotes efficiency, sometimes <strong>copy-paste is the better choice</strong> if it preserves clarity and independence.</p><p>For example imagine you have methods to send notifications The first example is focused a lot on the DRY principle, that it breaks single-responsibility.</p><pre><code>function sendNotification(recipient, message, type) {
  const formattedMessage = formatMessage(type, message);
  const validatedRecipient = validateRecipient(type, recipient);
  send(type, validatedRecipient, formattedMessage);
}

function formatMessage(type, message) {
  if (type === 'email') return formatEmailMessage(message);
  if (type === 'sms') return formatSMSMessage(message);
  // other types...
}

function validateRecipient(type, recipient) {
  if (type === 'email' &amp;&amp; !isValidEmail(recipient)) {
    throw new Error('Invalid email');
  }
  if (type === 'sms' &amp;&amp; !isValidPhoneNumber(recipient)) {
    throw new Error('Invalid phone number');
  }
  // other types...
}</code></pre><p>The second example strikes the balance between both only if you have to send two or more types of notifications. And we can argue that it would have broke the You Aint Gonna Need It (YAGNI) principle if done when having one type of notification to send.</p><pre><code>class Notification {
  constructor(recipient, message) {
    this.recipient = recipient;
    this.message = message;
  }

  validate() {
    throw new Error('Validate method must be implemented.');
  }

  format() {
    throw new Error('Format method must be implemented.');
  }

  send() {
    throw new Error('Send method must be implemented.');
  }

  process() {
    this.validate();
    const formattedMessage = this.format();
    this.send(formattedMessage);
  }
}

class EmailNotification extends Notification {
  validate() {
    if (!isValidEmail(this.recipient)) {
      throw new Error('Invalid email address');
    }
  }

  format() {
    return formatEmailMessage(this.message);
  }

  send(formattedMessage) {
    sendEmail(this.recipient, formattedMessage);
  }
}

class SMSNotification extends Notification {
  validate() {
    if (!isValidPhoneNumber(this.recipient)) {
      throw new Error('Invalid phone number');
    }
  }

  format() {
    return formatSMSMessage(this.message);
  }

  send(formattedMessage) {
    sendSMS(this.recipient, formattedMessage);
  }
}</code></pre><p>This brings us to the other challenge we need to stay aware of, over engineering.</p><h2><strong>The Cost of Over engineering</strong></h2><p>SOLID principles aim to make software more robust and flexible, but rigid adoption can result in needless complexity. In the example above, implementing an elaborate inheritance hierarchy for a single-use case might violate YAGNI (You Aren&#8217;t Gonna Need It).</p><p>Creating a balance between extensibility and simplicity is crucial, especially when refactoring. The focus should alway be on what we have now, as it is what will resolve business impacting side effects. Immediate business impact should be prioritized, and the technical goals should be aligned with adding business value. This will make it easier to get a buy in from stakeholders with all the competing priorites.</p><h2><strong>Competing Priorities</strong></h2><p>Deadlines often trump code cleanliness. Developers must weigh the costs of refactoring against delivering features on time. In some cases, the immediate business impact of shipping outweighs the long-term benefits of a cleaner codebase.</p><h2><strong>Strategies for Real-World Refactoring</strong></h2><ol><li><p><strong>Focus on Business-Critical Code </strong>Prioritize refactoring areas that directly impact business outcomes. For example, improving the performance of a payment processing module is more valuable than cleaning up an infrequently used admin tool.</p></li><li><p><strong>Refactor Incrementally </strong>Big-bang refactors are risky and time- consuming. Instead, adopt the <strong>Boy Scout Rule</strong>: leave the code cleaner than you found it. Small, incremental changes accumulate over time, making the codebase more maintainable without disrupting ongoing development.</p></li><li><p><strong>When to break DRY: </strong>If two pieces of code are similar but exist in different contexts, duplicating them might be better than introducing a shared dependency.</p></li><li><p><strong>When to break SOLID:</strong> Violating the Single Responsibility Principle (SRP) might be acceptable in a stable, low-risk module where the cost of abstraction outweighs the benefits.</p></li><li><p><strong>Test-Driven Refactoring</strong>: Before refactoring, write tests to capture the current behavior of the code. These tests act as a safety net, ensuring that changes don&#8217;t introduce new bugs. Refactoring is much safer when you can verify functionality at every step.</p></li></ol><h2><strong>Practical Examples of Real-World Refactoring</strong></h2><h2><strong>1. Simplifying a Monolithic Function</strong></h2><p><strong>Before:</strong></p><pre><code>function calculateOrder(customer, items) {
  let discount = 0;
  if (customer.type === 'premium') {
    discount = items.length &gt; 5 ? 0.2 : 0.1;
  }
  let total = items.reduce((sum, item) =&gt; sum + item.price, 0);
  total -= total * discount;
  if (customer.hasLoyaltyCard) {
    total *= 0.95;
  }
  return total;
}</code></pre><p><strong>After:</strong></p><pre><code>function calculateOrder(customer, items) {
  const discount = getDiscount(customer, items);
  let total = calculateTotal(items, discount);
  return applyLoyaltyDiscount(customer, total);
}

function getDiscount(customer, items) {
  if (customer.type !== 'premium') return 0;
  return items.length &gt; 5 ? 0.2 : 0.1;
}

function calculateTotal(items, discount) {
  return items.reduce((sum, item) =&gt; sum + item.price, 0) * (1 - discount);
}

function applyLoyaltyDiscount(customer, total) {
  return customer.hasLoyaltyCard ? total * 0.95 : total;
}</code></pre><p>Breaking the function into smaller methods makes it easier to understand and test.</p><h2><strong>2. Avoiding Over-Abstraction</strong></h2><p>Suppose you have two similar but not identical processes:</p><pre><code>function renderPDF(document) {
  // Render PDF logic
}

function renderImage(document) {
  // Render Image logic
}</code></pre><p>Abstracting this might create unnecessary complexity if their shared logic is minimal. Instead, leaving them separate maintains clarity and independence.</p><h2><strong>When Not to Refactor</strong></h2><p>Refactoring isn&#8217;t always the right choice. Avoid it when:</p><ol><li><p><strong>Deadlines are tight:</strong> Focus on delivering functionality unless refactoring is necessary for the feature.</p></li><li><p><strong>The code is stable:</strong> Refactoring low-risk, rarely updated code offers little value.</p></li><li><p><strong>It adds complexity:</strong> Don&#8217;t refactor for refactoring&#8217;s sake; changes should simplify the code.</p></li></ol><h2><strong>Balancing Effectiveness and Principles</strong></h2><p>Software engineering is as much about making trade-offs as it is about following principles. DRY and SOLID are excellent guidelines but shouldn&#8217;t be dogmatically applied. Effective refactoring is about balancing perfection with the real world challenges of time, resources, and business priorities. Remember, Better is better than perfect.</p><p><em><strong><br>&#128038; <a href="https://x.com/EffectiveEng">Follow me on X</a></strong></em></p><p><em><strong>&#128073; <a href="http://www.effective-engineer.com/">Checkout my blog</a></strong></em></p><p></p><p>Support me in creating more content by subscribing!</p>]]></content:encoded></item><item><title><![CDATA[How to Debug Production: Handling Hot Fixes]]></title><description><![CDATA[Learn how to effectively handle production bugs and implement hotfixes with actionable steps, best practices, and tools for a seamless debugging process.]]></description><link>https://www.effective-engineer.com/p/how-to-debug-production-handling</link><guid isPermaLink="false">https://www.effective-engineer.com/p/how-to-debug-production-handling</guid><dc:creator><![CDATA[Effective Engineering]]></dc:creator><pubDate>Tue, 31 Dec 2024 08:22:44 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!pm1p!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d5785b1-aede-4415-ae51-a9582c464530_512x512.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Handling live issues is one of the risky responsibilities of a software engineer, that all of us wish to never have to face dealing with.</p><p>This guide focuses on actionable steps to handle production bugs and implement hot fixes effectively, along with real-world use cases to illustrate best practices.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pm1p!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d5785b1-aede-4415-ae51-a9582c464530_512x512.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pm1p!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d5785b1-aede-4415-ae51-a9582c464530_512x512.png 424w, https://substackcdn.com/image/fetch/$s_!pm1p!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d5785b1-aede-4415-ae51-a9582c464530_512x512.png 848w, https://substackcdn.com/image/fetch/$s_!pm1p!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d5785b1-aede-4415-ae51-a9582c464530_512x512.png 1272w, https://substackcdn.com/image/fetch/$s_!pm1p!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d5785b1-aede-4415-ae51-a9582c464530_512x512.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pm1p!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d5785b1-aede-4415-ae51-a9582c464530_512x512.png" width="512" height="512" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7d5785b1-aede-4415-ae51-a9582c464530_512x512.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:512,&quot;width&quot;:512,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!pm1p!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d5785b1-aede-4415-ae51-a9582c464530_512x512.png 424w, https://substackcdn.com/image/fetch/$s_!pm1p!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d5785b1-aede-4415-ae51-a9582c464530_512x512.png 848w, https://substackcdn.com/image/fetch/$s_!pm1p!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d5785b1-aede-4415-ae51-a9582c464530_512x512.png 1272w, https://substackcdn.com/image/fetch/$s_!pm1p!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d5785b1-aede-4415-ae51-a9582c464530_512x512.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"></figcaption></figure></div><h2><strong>How to Decide If a Hot fix Is Needed</strong></h2><p>This is where fear usually takes over without a proper framework. I have seen cases where a hot fix was requested for a broken loader icon that had no impact on flow, Or for an issue that was affecting 2 users from our 500k monthly active users.</p><p>Bugs exist in every system and fixing them is essential for the user experience. But having hot fixes and late nights without the need to do so destroys team morale, and creates an unhealthy work environment.</p><p>To determine if a hot fix is necessary, I like to ask the following:</p><ol><li><p>Is it costing us money?</p></li><li><p>Is it disrupting key user flows?</p></li><li><p>Is it harming trust or reputation?</p></li><li><p>Is it increasing operations effort or risking compliance?</p></li></ol><p>If the impact is significant and the answer to any of the above is yes, I will prioritize the hot fix.</p><h1><strong>Be prepared before incidents happen</strong></h1><p>A framework to handle incidents does not look like something that would be prioritized until an issue actually happens. It is crucial to define a framework that guides the team on how to deal with a production incident. An effective framework ensures clarity and minimizes chaos when handling production bugs.</p><p>This is how to create an incident handling process</p><ul><li><p><strong>Define Severity Levels:</strong> Create criteria to classify incidents as Critical, High, or Low based on user impact. For example, a payment gateway outage is Critical, while a minor UI glitch may be Low. Questions mentioned above can help.</p></li><li><p><strong>Escalation Workflows:</strong> Set clear paths for escalating issues, from on-call engineers to team leads or SRE teams.</p></li><li><p><strong>Prepare Run books:</strong> Document step-by-step responses for common issues to guide engineers during incidents.</p></li></ul><h2><strong>Monitoring and Detection for Engineers</strong></h2><p>Early detection of production issues minimizes its impact and speeds up resolution. Monitoring is a core part of engineering, relying on real-time dashboards and smart alerts to catch issues before users notice is crucial for a brand&#8217;s image, user experience.</p><p>It also prevents revenue loss which can make or break a company in its early days.Be proactive and set up tools that will help in early detection and debugging. This can be done by setting up the following:</p><ul><li><p><strong>Monitor Critical Metrics</strong>:<br>Track latency, error rates, and resource usage with tools like Grafana, New Relic, or Datadog.</p></li><li><p><strong>Set Smart Alerts</strong>:<br>Avoid alert fatigue by using actionable thresholds (e.g., &#8220;API error rate &gt; 5% for 10 minutes&#8221;).</p></li><li><p><strong>Enhance Observability</strong>:<br>Use structured logs, traces, and metrics that are easily searchable for faster debugging.</p></li><li><p><strong>Automate Anomaly Detection</strong>:<br>Implement tools like Prometheus alert manager or ML-based systems to catch unusual patterns early.</p><h2><strong>Debugging in Live Environments</strong></h2><p>Begin by examining logs and metrics to identify anomalies and narrow down potential root causes.I usually need to look at logs from different parts of the system to be able to create a pattern and understand the issue. The key goal here is to create a sequence of steps or pattern of actions that once it occurs the bug happens.</p><p>To do this we can use targeted debugging tools, such as trace analyzers or runtime loggers, to gather more insights directly from the production system.</p><p>Once we have this understanding we should aim to replicate the issue in a staging environment If possible to validate the findings and avoid risky live experimentation.</p><p>The following action items helps when debugging live:</p><ul><li><p><strong>Start with Logs and Metrics:</strong> Analyze structured logs and metrics to identify anomalies before making live changes.</p></li><li><p><strong>Replicate Safely:</strong> Attempt to replicate the issue in a staging environment to confirm root causes without affecting users.</p></li><li><p><strong>Use Feature Toggles:</strong> Temporarily disable problematic features or isolate the impact without rolling back the entire system.</p></li><li><p><strong>Document Every Step:</strong> Record your debugging actions to create a clear trail for post-incident analysis.</p></li></ul><h2><strong>Communication During Incidents</strong></h2><p>Keep updates clear and short. Share the issue, its impact, and when it will be fixed for example, &#8220;Payment processing is delayed due to a gateway issue; expected resolution in 30 minutes&#8221;. Use tools like Slack, PagerDuty, or StatusPage to communicate. Work closely with support teams to give users accurate updates. Make sure to only share confirmed details to avoid confusion.</p><h2><strong>Post-Incident Reviews for Engineers</strong></h2><p>A strong post-incident review is crucial for learning and preventing future issues. Following an approach of blameless postmortems, focus on system and process failures, not individual mistakes (e.g., &#8220;The alert threshold was too high to detect the issue sooner&#8221;).</p><h2><strong>What makes a good postmortem</strong></h2><p>A good postmortem should include a detailed timeline of events, root causes (technical, procedural, and human), and the incident&#8217;s impact. Ensure all findings are based on facts to avoid blame and to ensure a safe discussion environment.</p><p>To make postmortems actionable, define clear tasks such as refining alert thresholds, improving test coverage, or updating runbooks, this will foster a culture of continuous learning and resilience.</p><p>Define clear tasks: Refine alert thresholds, improve test coverage, update run books. Here is a guideline that I post about a production bug.</p><ul><li><p>Standardize the process: define and use a common RCA templates that answers what happened, action taken, and how can we prevent it and lessons learned.</p></li><li><p>Prioritize tasks: Focus on high-impact action items first.</p></li><li><p>Track progress: Ensure all action items are completed.</p></li><li><p>Share insights: Distribute findings across teams to prevent similar issues.</p></li><li><p>Measure success: Use metrics like MTTR or incident recurrence rates.</p></li></ul><h2><strong>Conclusion</strong></h2><p>Dealing with production bugs and hot fixes is as much about preparation and process as it is about technical expertise. By setting up robust incident response frameworks, leveraging monitoring tools, communicating effectively, and learning from incidents, software engineers can handle live issues confidently and minimize user impact. Embrace these practices to not only resolve issues faster but also build systems that are more resilient and reliable in the long run.</p></li></ul><p></p><p><strong>Support me in creating more content by subscribing !</strong></p>]]></content:encoded></item><item><title><![CDATA[Effective Release Management: An Ultimate Guide]]></title><description><![CDATA[Key strategies for pre-release preparation, coordination, post-release monitoring, and success metrics to ensure smooth, efficient software deployments]]></description><link>https://www.effective-engineer.com/p/effective-release-management-an-ultimate</link><guid isPermaLink="false">https://www.effective-engineer.com/p/effective-release-management-an-ultimate</guid><dc:creator><![CDATA[Effective Engineering]]></dc:creator><pubDate>Mon, 30 Dec 2024 13:05:54 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!pWzm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30dbe74b-52ca-4fd7-bdab-47928a175a5a_512x512.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When I first started working in release management I was an engineer at a startup where everyone wears a lot of hats. At the start, the process seemed overwhelming. As a relatively new engineer, I remember the first major release I was part of. There were so many moving parts, and it felt like everything could go wrong at any moment. However, over time, I learned that managing releases isn&#8217;t the &#8220;throw and see what sticks&#8221; process it seemed to be.<br>In Big tech, release engineers are there to help, but this is not the case everywhere. In this guide, we&#8217;ll dive into every aspect of managing releases, from pre-release preparation to post-launch monitoring, all with a focus on making the process seamless and efficient regardless if you work with release engineers or not.</p><h2><strong>The Backbone of a Smooth Release Process</strong></h2><p>The importance of a structured release process is unmatched. A structured process minimizes risk, enhances collaboration across teams, and allows for quick recovery when things go wrong. It also can make or break the work-life balance of your team.<br>I&#8217;ve seen firsthand how a lack of preparation can lead to disastrous results. In one instance, we had a major release planned, but we overlooked a critical dependency between services. The operations team wasn&#8217;t informed about the need to update a shared configuration before deployment.The result? The primary service failed to start in production</p><h2><strong>Pre-Release: Laying the Foundation</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pWzm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30dbe74b-52ca-4fd7-bdab-47928a175a5a_512x512.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pWzm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30dbe74b-52ca-4fd7-bdab-47928a175a5a_512x512.png 424w, https://substackcdn.com/image/fetch/$s_!pWzm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30dbe74b-52ca-4fd7-bdab-47928a175a5a_512x512.png 848w, https://substackcdn.com/image/fetch/$s_!pWzm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30dbe74b-52ca-4fd7-bdab-47928a175a5a_512x512.png 1272w, https://substackcdn.com/image/fetch/$s_!pWzm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30dbe74b-52ca-4fd7-bdab-47928a175a5a_512x512.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pWzm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30dbe74b-52ca-4fd7-bdab-47928a175a5a_512x512.png" width="512" height="512" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/30dbe74b-52ca-4fd7-bdab-47928a175a5a_512x512.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:512,&quot;width&quot;:512,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!pWzm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30dbe74b-52ca-4fd7-bdab-47928a175a5a_512x512.png 424w, https://substackcdn.com/image/fetch/$s_!pWzm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30dbe74b-52ca-4fd7-bdab-47928a175a5a_512x512.png 848w, https://substackcdn.com/image/fetch/$s_!pWzm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30dbe74b-52ca-4fd7-bdab-47928a175a5a_512x512.png 1272w, https://substackcdn.com/image/fetch/$s_!pWzm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30dbe74b-52ca-4fd7-bdab-47928a175a5a_512x512.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>Code Freeze and Final Testing</strong></h2><p>The pre-release phase is critical. This is when your code is finally ready for deployment, and it&#8217;s time to ensure everything works as intended. For me, the first step in this phase was always the &#8220;code freeze.&#8221; I learned that the real power of a code freeze is in reducing risk.</p><p>Code freeze does not mean engineers stop writing code, But it simply means that for the tag being released, there will be no additions, just fixes. By halting all new feature development and put a hard limit on the scope of release which allows focus on testing. This is how we could ensure stability.</p><p>Final testing happens during this phase, where final integration and user acceptance testing happens.</p><h2><strong>Cross-Team Coordination</strong></h2><p>Releases require alignment across multiple teams, including developers, QA, product managers, operations, and other cross-functional teams. Poor coordination can lead to misalignment, rushed processes, and frustration.</p><p>To ensure seamless cross-team coordination:</p><ol><li><p><strong>Establish a shared timeline</strong>: Create a clear release schedule that all teams agree on and understand.</p></li><li><p><strong>Host regular syncs</strong>: Schedule check-ins to track progress, surface blockers, and ensure alignment. This can be a slack channel, or an email thread.</p></li><li><p><strong>Document everything</strong>: Maintain shared documentation with roles, responsibilities, and key milestones for full transparency.</p></li><li><p><strong>Assign points of contact</strong>: Designate a representative for each team to streamline communication and resolve issues quickly.</p></li></ol><p>By prioritizing cross-team alignment, you reduce the risk of last-minute surprises and create a foundation for a smooth and successful release process.</p><h2><strong>User documentation</strong></h2><p>In B2B software, comprehensive documentation is critical for ensuring smooth releases and minimizing confusion. It&#8217;s easy to assume that everyone, from internal teams to clients, knows what to expect from a release, but gaps in understanding can lead to disruptions.</p><p>To ensure effective documentation:</p><ol><li><p><strong>Internal Documentation</strong>: Share release notes, deployment steps, and rollback strategies with all relevant teams to align everyone on the process.</p></li><li><p><strong>Client-Facing Documentation</strong>: Provide detailed guides, FAQs, and implementation resources to help clients quickly adopt and integrate new features.</p></li><li><p><strong>Client Education</strong>: In B2B, user education can play a significant role in reducing support tickets, increasing feature adoption, and ensuring clients are fully equipped to leverage new functionality.</p></li></ol><p>By focusing on thorough internal and client-facing documentation, you build trust and ensure a smoother, more successful release in B2B environments.</p><h2><strong>Post-Release: Monitoring and Response</strong></h2><h2><strong>1. Monitoring the System After Deployment</strong></h2><p>Once your release is live, the real work begins. I learned this lesson the hard way during a release where everything seemed fine during testing, but performance metrics after launch were disastrous. The system started to lag, and we realized that we hadn&#8217;t anticipated the volume of traffic the new feature would attract. It was an intense learning moment. Ever since, I&#8217;ve been a strong advocate for post-release monitoring.</p><p>Tools like New Relic, Datadog, and Prometheus have become a critical part of my workflow. They allow me to track key performance indicators (KPIs) in real-time. By monitoring things like uptime, load times, and error rates immediately after a release, I can quickly spot and address potential issues. Early detection is key to maintaining a positive user experience and preventing long-term problems.</p><h2><strong>2. Stakeholder Communication</strong></h2><p>In the rush of deployment, it&#8217;s easy to forget to keep stakeholders informed. However, I&#8217;ve found that timely communication is vital. Forgetting to keep the stakeholders updated on the status will get them caught off guard when users report bugs, and it will delay their ability to address issues.</p><p>I always ensure that communication channels are open, and all relevant stakeholders receive timely updates. Whether it&#8217;s a quick email or a formal meeting, keeping everyone in the loop ensures transparency, trust, and the ability to react quickly if things go wrong.</p><h2><strong>3. Success Metrics for Releases</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9Y0g!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9f21b2a-743b-44e9-930a-dcbf5c887bb4_1400x907.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9Y0g!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9f21b2a-743b-44e9-930a-dcbf5c887bb4_1400x907.png 424w, https://substackcdn.com/image/fetch/$s_!9Y0g!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9f21b2a-743b-44e9-930a-dcbf5c887bb4_1400x907.png 848w, https://substackcdn.com/image/fetch/$s_!9Y0g!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9f21b2a-743b-44e9-930a-dcbf5c887bb4_1400x907.png 1272w, https://substackcdn.com/image/fetch/$s_!9Y0g!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9f21b2a-743b-44e9-930a-dcbf5c887bb4_1400x907.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9Y0g!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9f21b2a-743b-44e9-930a-dcbf5c887bb4_1400x907.png" width="1400" height="907" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d9f21b2a-743b-44e9-930a-dcbf5c887bb4_1400x907.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:907,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!9Y0g!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9f21b2a-743b-44e9-930a-dcbf5c887bb4_1400x907.png 424w, https://substackcdn.com/image/fetch/$s_!9Y0g!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9f21b2a-743b-44e9-930a-dcbf5c887bb4_1400x907.png 848w, https://substackcdn.com/image/fetch/$s_!9Y0g!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9f21b2a-743b-44e9-930a-dcbf5c887bb4_1400x907.png 1272w, https://substackcdn.com/image/fetch/$s_!9Y0g!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9f21b2a-743b-44e9-930a-dcbf5c887bb4_1400x907.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Measuring the success of a release goes beyond tracking uptime or bug reports. We should evaluate whether the release met its objectives and delivered value to users.</p><p>Clear success metrics before every release could include:</p><ul><li><p><strong>User Engagement</strong>: Metrics such as daily active users (DAU), feature usage rates, or time spent on key features.</p></li><li><p><strong>Customer Satisfaction</strong>: Net Promoter Score (NPS), customer feedback surveys, or support ticket volume post-release.</p></li><li><p><strong>Performance Metrics</strong>: Load times, error rates, or system performance improvements.</p></li><li><p><strong>Business Outcomes</strong>: Conversion rates, customer retention rates, or even revenue growth linked to the release.</p></li></ul><p>By tracking these success metrics, you ensure that we&#8217;re delivering real value and can make informed decisions about future releases. It will improve your knowledge of the business and help you contribute more value when discussing future work.</p><h2><strong>Elevating Your Release Process</strong></h2><h2><strong>1. Feature Toggles and A/B Testing</strong></h2><p>This approach allows you to push code live without exposing it to users immediately. it also enables you to toggle features on or off without redeploying code, providing flexibility and a solid backup plan.</p><p>When Facebook launched the News Feed redesign, they relied heavily on feature toggles to control access to the update. This allowed the engineering team to roll out the feature gradually, monitor performance, and gather user feedback.</p><p>Coupled with A/B testing, they compared user engagement metrics between the new and old designs, using the insights to iterate quickly. By refining the design based on real-world data, Facebook ensured the final release met user expectations while minimizing risk.</p><p>Feature toggles and A/B testing together empower teams to make safe, data-driven decisions, enabling gradual rollouts, rapid experimentation, and continuous improvement.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DCc5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36168d9b-ee5e-40f8-aa92-eb6babbf5652_557x492.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DCc5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36168d9b-ee5e-40f8-aa92-eb6babbf5652_557x492.png 424w, https://substackcdn.com/image/fetch/$s_!DCc5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36168d9b-ee5e-40f8-aa92-eb6babbf5652_557x492.png 848w, https://substackcdn.com/image/fetch/$s_!DCc5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36168d9b-ee5e-40f8-aa92-eb6babbf5652_557x492.png 1272w, https://substackcdn.com/image/fetch/$s_!DCc5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36168d9b-ee5e-40f8-aa92-eb6babbf5652_557x492.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DCc5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36168d9b-ee5e-40f8-aa92-eb6babbf5652_557x492.png" width="557" height="492" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/36168d9b-ee5e-40f8-aa92-eb6babbf5652_557x492.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:492,&quot;width&quot;:557,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!DCc5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36168d9b-ee5e-40f8-aa92-eb6babbf5652_557x492.png 424w, https://substackcdn.com/image/fetch/$s_!DCc5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36168d9b-ee5e-40f8-aa92-eb6babbf5652_557x492.png 848w, https://substackcdn.com/image/fetch/$s_!DCc5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36168d9b-ee5e-40f8-aa92-eb6babbf5652_557x492.png 1272w, https://substackcdn.com/image/fetch/$s_!DCc5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36168d9b-ee5e-40f8-aa92-eb6babbf5652_557x492.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>2. Continuous Delivery and Deployment</strong></h2><p>Continuous delivery (CD) and continuous deployment practices emphasize automating the build, testing, and deployment pipelines to ensure smooth and consistent delivery of updates.</p><p>Google&#8217;s engineering teams are well-known for their robust releasing system. For instance, Google Search&#8217;s continuous delivery pipeline processes thousands of daily code changes all done on a huge mono repo.</p><p>Engineers push updates to production multiple times a day, relying on automated testing to catch issues early. The process ensures that every code change is thoroughly vetted before deployment, maintaining the quality and reliability users expect. Google&#8217;s strategy also includes extensive monitoring and rollback mechanisms, allowing them to address any issues.</p><p>By adopting continuous delivery, we can deliver features and fixes faster while maintaining high quality. The key lies in rigorous testing, seamless automation, and proactive monitoring.</p><h2><strong>3. Managing Large-Scale Releases</strong></h2><p>As projects scale, managing releases becomes increasingly complex, involving coordination across multiple teams and systems. Large-scale releases require careful planning, communication, and risk mitigation strategies.</p><p>A classic case study is Google Chrome&#8217;s rollout strategy. Given Chrome&#8217;s massive user base, updates must be flawless. Google employs a staged rollout approach, initially releasing updates to a small percentage of users.</p><p>They monitor feedback and performance metrics closely, scaling up the release incrementally. This method helps identify and address issues early, ensuring the broader user base isn&#8217;t impacted. For complex updates, Google coordinates across engineering, product, and customer support teams to ensure alignment and preparedness.</p><p>Key strategies for large-scale releases include breaking down releases into manageable chunks, staged rollouts, and having a clear rollback plan. Effective communication and dependency management are also critical to minimizing risks.</p><h2><strong>The Continuous Journey of Release Management</strong></h2><p>Release management is a dynamic and ongoing learning process. Each release presents new challenges and lessons, helping refine the approach for future launches. With a solid process, effective communication across teams, and a focus on monitoring and measuring success, every release can bring value to users and the team.</p><p>As seen in the examples of Facebook and Google, mastering release management goes beyond technical skills. It requires understanding the broader impact of each release on the product, team, and end-users. Whether you&#8217;re starting out or leading releases at scale, remember that each release is an opportunity to improve, learn, and grow as an engineer.</p><p>Start small perhaps by formalizing your code freeze procedures, improving your monitoring tools, or conducting regular post-release retrospectives with your team, with time your process will mature to fit product needs.</p><p>&#128073; <a href="https://effective-eng.medium.com/">Follow me on Medium</a><br>&#128038; <a href="https://x.com/EffectiveEng">Follow me on X</a></p>]]></content:encoded></item><item><title><![CDATA[Quality Code: Testing Legacy and Scalable Systems]]></title><description><![CDATA[From zero to mastering testing strategies, from legacy code tests to ensuring scalability software.]]></description><link>https://www.effective-engineer.com/p/quality-code-testing-legacy-and-scalable</link><guid isPermaLink="false">https://www.effective-engineer.com/p/quality-code-testing-legacy-and-scalable</guid><dc:creator><![CDATA[Effective Engineering]]></dc:creator><pubDate>Sun, 29 Dec 2024 17:14:57 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!vU7j!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf55a1db-2e36-454b-b427-3885105bd789_1400x1400.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div><hr></div><p>Shipping High quality software that stays that way is a hard task. It&#8217;s easy to fall into the trap of writing code that works now but becomes a burden as your application grows.</p><p>To maintain consistent, high-quality code, you need to build the foundation that prioritizes <strong>testing</strong>, and <strong>code quality</strong>.</p><p>This guide offers practical steps to write high-quality tests by focusing on testing strategies, design principles, techniques to make your software scalable and maintainable, and tips for working with legacy code.</p><h4>The Testing Pyramid: A Balanced Approach</h4><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vU7j!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf55a1db-2e36-454b-b427-3885105bd789_1400x1400.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vU7j!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf55a1db-2e36-454b-b427-3885105bd789_1400x1400.png 424w, https://substackcdn.com/image/fetch/$s_!vU7j!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf55a1db-2e36-454b-b427-3885105bd789_1400x1400.png 848w, https://substackcdn.com/image/fetch/$s_!vU7j!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf55a1db-2e36-454b-b427-3885105bd789_1400x1400.png 1272w, https://substackcdn.com/image/fetch/$s_!vU7j!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf55a1db-2e36-454b-b427-3885105bd789_1400x1400.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vU7j!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf55a1db-2e36-454b-b427-3885105bd789_1400x1400.png" width="1400" height="1400" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cf55a1db-2e36-454b-b427-3885105bd789_1400x1400.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1400,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!vU7j!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf55a1db-2e36-454b-b427-3885105bd789_1400x1400.png 424w, https://substackcdn.com/image/fetch/$s_!vU7j!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf55a1db-2e36-454b-b427-3885105bd789_1400x1400.png 848w, https://substackcdn.com/image/fetch/$s_!vU7j!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf55a1db-2e36-454b-b427-3885105bd789_1400x1400.png 1272w, https://substackcdn.com/image/fetch/$s_!vU7j!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf55a1db-2e36-454b-b427-3885105bd789_1400x1400.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Before diving into specific testing practices, let me start by introducing the <strong>Testing Pyramid</strong>.</p><p>This model helps us understand the importance of different types of tests at different levels:</p><ol><li><p><strong>Unit Tests</strong>: These test individual functions or components in isolation. They should be precise, small and cover the smallest units of code.</p></li><li><p><strong>Integration Tests</strong>: These test how different modules or components interact with each other.</p></li><li><p><strong>End-to-End (E2E) Tests</strong>: These simulate real user workflows to test the full system from start to finish. While they are comprehensive, they should be limited to critical paths.</p></li></ol><p>The goal is to have a strong base of unit tests, a solid middle layer of integration tests, and a minimal set of E2E tests to cover critical features. Each level of the pyramid handles prevent a different set of issues that could happen. It helps in ensuring that your application is covered without being over-tested.The next step is to ensure your code is designed to be testable</p><div><hr></div><h4>Writing Testable Code: Principles and Examples</h4><p>Good testing start with <strong>writing testable code</strong>. The easier it is to isolate and test your code, the more confident you&#8217;ll be in its correctness.</p><p>Here are some principles to follow:</p><ol><li><p><strong>Separation of Concerns</strong>: Each module should have a single responsibility.</p></li><li><p><strong>Dependency Injection</strong>: Pass dependencies into functions rather than creating them inside.</p></li><li><p><strong>Avoid Side Effects</strong>: Write pure functions wherever possible.</p></li><li><p><strong>Modular Design</strong>: Break large functions into smaller, reusable ones.</p></li></ol><h4>Designing our code for tests</h4><p>Let&#8217;s take a look at a real-world example of how refactoring code for testability can lead to more maintainable and testable components.</p><p><strong>Before Refactoring</strong>:<br>In this example, the code directly handles business logic, sends emails, and calculates totals in one function.</p><pre><code>function processOrder(order) {
  const discount = order.amount &gt; 100 ? 0.1 : 0;
  const total = order.amount - order.amount * discount;
  sendEmail(order.email, `Total: $${total}`);
}</code></pre><p>This function is difficult to test because it directly calls <code>sendEmail</code>. Also, the logic for calculating the discount and total is mixed into one function.</p><p><strong>After Refactoring</strong>:<br>We can separate the concerns, making each function independently testable.</p><pre><code>function calculateDiscount(amount) {
  return amount &gt; 100 ? 0.1 : 0;
}</code></pre><pre><code>function calculateTotal(order) {
  const discount = calculateDiscount(order.amount);
  return order.amount - order.amount * discount;
}</code></pre><pre><code>function processOrder(order, emailSender) {
  const total = calculateTotal(order);
  emailSender(order.email, `Total: $${total}`);
}</code></pre><p>Now, <code>calculateDiscount</code>, <code>calculateTotal</code>, and <code>processOrder</code> are all independent and can be tested individually. This makes the code easier to maintain and scale.</p><p>Now let&#8217;s explore tools to implement your tests effectively<em>.</em></p><div><hr></div><h3>Jest : A Quick intro</h3><p>Now that we have the testing pyramid in mind, and are able to write testable code, that is easy to refactor. let&#8217;s look at <strong>Jest</strong>, one of the most popular testing libraries.</p><p>Jest makes it easy to start testing your JavaScript code with powerful features such as mocking, snapshot testing, and more.</p><h4>Core Concepts in Jest</h4><p><strong>Test Suites and Test Cases</strong>:</p><ul><li><p>A <em>test suite</em> groups related test cases in a single file.</p></li><li><p>A <em>test case</em> verifies a specific piece of functionality.</p></li></ul><p><strong>Matchers</strong>: Methods used to validate the results of your functions.</p><ul><li><p><code>toBe()</code>: Strict equality check.</p></li><li><p><code>toEqual()</code>: Deep equality check.</p></li><li><p><code>toHaveBeenCalled()</code>: Ensures a mock function was called.</p></li></ul><h4>Mocking with Jest</h4><p>Mocks allow us to simulate external dependencies and isolate the functionality we want to test. This is especially useful when testing code that interacts with APIs, databases, or external services.</p><pre><code>const mockApiClient = jest.fn().mockResolvedValue({ data: { temp: 25 } });</code></pre><pre><code>async function fetchWeatherData(apiClient) {
  return apiClient();
}</code></pre><pre><code>// Test
test('fetchWeatherData calls API and returns temperature', async () =&gt; {
  const data = await fetchWeatherData(mockApiClient);
  expect(mockApiClient).toHaveBeenCalled();
  expect(data.temp).toBe(25);
});</code></pre><div><hr></div><h4>Handling legacy code</h4><p>Testing legacy code can be intimidating, but it&#8217;s a critical step in maintaining and improving it. Here&#8217;s how to approach it effectively:</p><h4>1. Identify Risky Areas</h4><p>Start by identifying parts of the codebase that are most likely to fail or have the greatest business impact. Focus your testing efforts there first.</p><h4>2. Characterization Tests</h4><p>Characterization tests capture the current behavior of the code. They serve as a baseline to ensure that changes don&#8217;t introduce regressions.</p><pre><code>// Legacy function
function calculateTotalLegacy(amount) {
  return amount * 1.2; // Includes tax
}</code></pre><pre><code>// Characterization test
test('calculateTotalLegacy returns correct total with tax', () =&gt; {
  expect(calculateTotalLegacy(100)).toBe(120);
});</code></pre><h4>3. Refactor for Testability</h4><p>Refactor small, isolated pieces of the code to make them testable. For example, extract complex logic into separate functions.</p><p><strong>4. Handling Legacy Code Isn&#8217;t always Possible</strong><br>When direct testing is not feasible (for example, if the legacy code is too tightly coupled or involves external dependencies that are hard to mock), here are a few approaches:</p><ul><li><p><strong>Integration Tests</strong>: Start by writing integration tests that cover critical paths. These tests can help capture the behavior of interconnected systems, even when individual units are hard to isolate.</p></li><li><p><strong>Refactoring in Stages</strong>: If direct testing isn&#8217;t possible due to complex legacy code, consider refactoring the code in stages. Break down large functions or components into smaller, testable parts. Test each small part incrementally as you refactor, ensuring that each change doesn&#8217;t introduce new issues. The proxy and strangler pattern can be great here.</p></li><li><p><strong>Don&#8217;t Aim for high testing coverage</strong>, rather focus on critical areas</p></li></ul><h4>5. Use Tools for Safety</h4><p>Tools like <strong>code coverage analysis</strong> and <strong>static analysis tools</strong> can help identify gaps in your tests and risky dependencies.</p><h4>6. Balance Tests and Development</h4><p>While testing is crucial, balance it with your project deadlines. Focus on high-risk areas when time is limited</p><h4>7. Utilize The Proxy Pattern</h4><p>The <strong>Proxy Pattern</strong> can be useful in testing legacy code by isolating external dependencies and making components more testable.</p><p>Here&#8217;s how it helps:</p><p><strong>1. Isolate Dependencies for Testing </strong>Legacy systems often rely on tightly coupled external services (e.g., databases, APIs). Using a proxy, you can simulate these dependencies, making it easier to test the logic in isolation.</p><p><strong>Example:</strong></p><pre><code>class PaymentGatewayProxy {
  process(order) {
    return order.amount &gt; 1000 ? { success: true } : { success: false };
  }
}</code></pre><p>In tests, you can replace the real payment gateway with this proxy, avoiding external calls while testing.</p><p><strong>2. Mock Behavior for Complex Operations</strong>: Proxies allow you to mock complex, slow, or resource-intensive operations (e.g., network requests, file I/O), speeding up tests.</p><p><strong>Example:</strong></p><pre><code>class FileSystemProxy {
  constructor(realFileSystem) {
    this.realFileSystem = realFileSystem;
    this.cache = {};  // Cache results
  }</code></pre><pre><code>readFile(filePath) {
    if (this.cache[filePath]) return this.cache[filePath];
    const content = this.realFileSystem.readFile(filePath);
    this.cache[filePath] = content;
    return content;
  }
}</code></pre><p>This proxy helps avoid hitting the actual file system during tests.</p><p><strong>3. Incremental Refactoring: </strong>The Proxy Pattern allows you to refactor legacy code incrementally. You can introduce proxies to abstract complex or tightly coupled components, making them easier to test while refactoring in stages.</p><p><strong>Example:</strong></p><pre><code>class LegacyServiceProxy {
  method() {
    // Proxy delegates to refactored, testable components
    return new RefactoredService().method();
  }
}</code></pre><p>This makes testing easier and reduces the risk of breaking functionality during refactoring.</p><h4>Recap:</h4><ul><li><p><strong>Isolate Dependencies</strong>: Simulate external services for isolated testing.</p></li><li><p><strong>Mock Expensive Operations</strong>: Avoid costly operations (e.g., file I/O) during tests.</p></li><li><p><strong>Incremental Refactoring</strong>: Introduce proxies to refactor legacy code without disrupting tests.</p></li></ul><p>By using the Proxy Pattern, you make legacy systems more testable, ensuring that tests are focused, efficient, and easier to maintain.</p><div><hr></div><h4>Testing for Scalability</h4><p>High-quality code isn&#8217;t just about correctness&#8202;&#8212;&#8202;it&#8217;s also about ensuring your code can handle increased complexity and growth over time, without introducing regressions or performance issues. Here&#8217;s how to integrate scalability with testing practices:</p><ol><li><p><strong>Test for Growth</strong><br>As your codebase grows, so do the number of edge cases and interactions between components. Write tests that anticipate how your system will handle increased load and complexity.<br><strong>Example</strong>: Write tests that simulate large datasets or increased user activity. This helps ensure that performance remains optimal under growing demand, especially when integrating new features.</p></li><li><p><strong>Optimize and Test for Performance</strong><br>Scalability also involves ensuring your code performs well as it expands. Performance testing helps identify bottlenecks before they become issues in production.<br><strong>Example</strong>: Use load testing tools like Jest or other performance profiling tools to test how your application handles large volumes of data, such as stress-testing database queries or large API responses.</p></li><li><p><strong>Test Caching and Data Access Patterns</strong><br>Caching is essential for scaling, but you need to ensure that your caching strategy doesn&#8217;t introduce bugs or inconsistencies. Write tests to validate that your caching mechanism works as expected.<br><strong>Example</strong>: Write unit and integration tests that check if cached data is updated correctly, ensuring no stale data is returned, and validate that caching doesn&#8217;t cause conflicts in concurrent requests.</p></li><li><p><strong>Database Queries and Test Coverage</strong><br>With the increase in data, the performance of your database queries becomes critical. Ensure you&#8217;re writing tests that validate query optimization and indexing.<br><strong>Example</strong>: Write integration tests that simulate large query responses and measure their performance, ensuring that the indexes and database optimizations handle large-scale operations efficiently.</p></li><li><p><strong>Modular Testing with Scalable Architectures</strong><br>In a microservices or serverless architecture, each service must be independently tested to ensure they can scale individually. Create modular test suites that can scale with your application&#8217;s growth.<br><strong>Example</strong>: Develop end-to-end tests that cover each microservice and ensure they function in isolation, as well as in combination with other services, without creating performance bottlenecks.</p></li></ol><p>By incorporating these scalability-focused testing practices, you ensure that your codebase remains maintainable, high-performing, and robust as it grows. Always test for scalability, not just functionality, to deliver quality code that stands the test of time.</p><div><hr></div><h3><strong>Final Thoughts</strong></h3><p>Testing is a critical practice for building high-quality software that lasts. writing tests improves your development process by:</p><p><strong>Building Confidence in Code:</strong><br>Tests act as a safety net, enabling you to make changes without fear of introducing bugs. For example, when adding a feature to apply discounts based on order amounts, writing tests for edge cases ensures the code behaves as expected under various conditions.</p><p><strong>Encouraging Better Design:</strong><br>Writing tests forces you to simplify and modularize your code, leading to better overall architecture and maintainability.</p><p><strong>Accelerating Debugging:</strong><br>Tests help identify and fix bugs early. For instance, if a negative amount is accidentally passed into the <code>applyDiscount</code> function, a test will catch it immediately, saving you hours of debugging later.</p><p><strong>Supporting Refactoring:</strong><br>Comprehensive tests give you the confidence to refactor. With tests in place, you can safely change or restructure parts of your code without worrying about breaking existing functionality.</p>]]></content:encoded></item><item><title><![CDATA[Before code: 4 steps for smarter software development]]></title><description><![CDATA[Learn a 4-step approach to smarter software development and deliver lasting value]]></description><link>https://www.effective-engineer.com/p/building-software-a-practical-guide</link><guid isPermaLink="false">https://www.effective-engineer.com/p/building-software-a-practical-guide</guid><dc:creator><![CDATA[Effective Engineering]]></dc:creator><pubDate>Sat, 28 Dec 2024 09:14:20 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!kxfR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff72b6839-b6ab-4579-afa7-0fc7079fdf69_1024x1024.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Every great engineer knows that success doesn&#8217;t come from just writing code, it&#8217;s about building systems that endure and deliver real value. Companies like Google, Meta, and Amazon have mastered the art of deliberate planning, turning ideas into impactful systems. Want to join the ranks of engineers who create with purpose?</p><p>This <strong>4-step guide</strong> will show you how to plan smarter, build better, and deliver value. If you master the skills in this guide, you will become a multiplier builder, whether you're creating for yourself or on the job.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.effective-engineer.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Effective Engineering @ effective-engineer.com! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!kxfR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff72b6839-b6ab-4579-afa7-0fc7079fdf69_1024x1024.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kxfR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff72b6839-b6ab-4579-afa7-0fc7079fdf69_1024x1024.webp 424w, https://substackcdn.com/image/fetch/$s_!kxfR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff72b6839-b6ab-4579-afa7-0fc7079fdf69_1024x1024.webp 848w, https://substackcdn.com/image/fetch/$s_!kxfR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff72b6839-b6ab-4579-afa7-0fc7079fdf69_1024x1024.webp 1272w, https://substackcdn.com/image/fetch/$s_!kxfR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff72b6839-b6ab-4579-afa7-0fc7079fdf69_1024x1024.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!kxfR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff72b6839-b6ab-4579-afa7-0fc7079fdf69_1024x1024.webp" width="1024" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f72b6839-b6ab-4579-afa7-0fc7079fdf69_1024x1024.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:304374,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!kxfR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff72b6839-b6ab-4579-afa7-0fc7079fdf69_1024x1024.webp 424w, https://substackcdn.com/image/fetch/$s_!kxfR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff72b6839-b6ab-4579-afa7-0fc7079fdf69_1024x1024.webp 848w, https://substackcdn.com/image/fetch/$s_!kxfR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff72b6839-b6ab-4579-afa7-0fc7079fdf69_1024x1024.webp 1272w, https://substackcdn.com/image/fetch/$s_!kxfR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff72b6839-b6ab-4579-afa7-0fc7079fdf69_1024x1024.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h4><strong>Step 1: Understand the Problem (Start With 'Why')</strong></h4><p>Before diving into writing code, we need to understand why we are doing this, what problem we are trying to solve. Getting these insights will allow you to evaluate the solution, add your input, or maybe argue that the proposed solution won't solve the problem and suggest a different solution.</p><p>Start with asking questions like:</p><ul><li><p><em>What problem are we solving?</em></p></li><li><p><em>Who</em> benefits from the solution?</p></li><li><p><em>What is the impact of not solving this problem?</em></p></li></ul><p>This clear understanding sets the foundation for you to understand what it is that we are trying to achieve and evaluate the effectiveness of the solution proposed, whether it will solve the problem at hand. Understanding the impact that will allow you to have a strong argument working on valuable items instead if it has more impact.</p><h4><strong>Step 2: Collaborate and Align</strong></h4><p>One of the important steps that gets missed all the time. The consequences of missing this can be severe: wasted time, unnecessary rework, and a final product that fails to meet its intended purpose.</p><p>To avoid this you should discuss with stakeholders to gather requirements, and ask about details. Make sure to think about constraints and edge cases.</p><p>At the end of this step, you should have a clear understanding of the following</p><ul><li><p><strong>What happens if the input is unexpected?</strong></p><ul><li><p>Examples: Empty, invalid, or extremely large values.</p></li></ul></li><li><p><strong>How does the system behave under high load or failure conditions?</strong></p><ul><li><p>Scenarios: Simulate heavy user traffic or resource limitations.</p></li></ul></li><li><p><strong>What external factors could introduce variability?</strong></p><ul><li><p>Examples: Third-party APIs, fluctuating network conditions, or unexpected dependencies.</p></li></ul></li><li><p><strong>What analytics events should be tracked?</strong></p><ul><li><p>Ensure key metrics are identified (e.g., success rates, failure patterns).</p></li><li><p>Determine whether to include an A/B test to evaluate feature impact or user behavior.</p></li></ul></li></ul><p>There should be a consensus between you and the stakeholders on what is going to be built.</p><h3><strong>Step 3: Translate High-Level Plans into Actionable Steps</strong></h3><p>Once you have alignment on the high-level plan, it's time to break it into smaller, manageable tasks. Translating an abstract idea into a clear roadmap is crucial to avoid confusion and ensure consistent progress.</p><h4><strong>How to Break It Down</strong></h4><ol><li><p><strong>Divide and Conquer:<br></strong>Break down the feature or project into logical phases, components, or milestones. Each should represent a distinct piece of work that adds value or aligns with a specific objective.</p></li><li><p><strong>Define SMART Tasks:<br></strong>Make each subtask <strong>Specific, Measurable, Achievable, Relevant, and Time-bound (SMART)</strong>. For example, instead of "Add authentication," create smaller tasks like "Implement login API," "Create UI for login page," and "Integrate OAuth."</p></li><li><p><strong>Identify Dependencies:<br></strong>Understand the sequence of tasks&#8212;what needs to happen first, and what can be done in parallel. This helps prioritize work effectively and prevents bottlenecks.</p></li><li><p><strong>Plan for Edge Cases:<br></strong>Include tasks for testing unexpected inputs, performance under load, and integration with external systems.</p></li></ol><p>At the end of this step, you should have:</p><ul><li><p>A detailed list of tasks or subtasks organized by priority and dependency.</p></li><li><p>Clear milestones for tracking progress and keeping stakeholders updated on steps, dependencies, and timeline.</p></li></ul><h4><strong>Step 4: Create the Design Document</strong></h4><p>To prevent unnecessary rework, delays, and frustration, <strong>create a thorough design document</strong>. have team members review it, and accept and discuss feedback in a kind-hearted manner.</p><p>To create a design document, I usually follow this thought process.</p><ol><li><p><strong>Define the Project Overview and Goals:</strong> Start by summarizing the project&#8217;s goals, objectives, and scope, including what's in and out of scope. Clearly articulate the problem the project solves and the specific outcomes you're aiming to achieve. This step ensures everyone understands both the <em>what</em> and <em>why</em>, aligning the team on the purpose and intended results.</p></li><li><p><strong>Find Dependencies, and Outline the Technical Approach:</strong> Identify task dependencies, and highlight potential risks and challenges. Detail the system architecture, components, and data flow. Include how different components interact, how you will deal with dependencies and the tools you will use.</p></li><li><p><strong>Security and Performance Considerations:</strong> Identify security measures, scalability, and performance strategies to ensure the system&#8217;s robustness and long-term viability.</p></li><li><p><strong>Testing Strategy:</strong> Outline the types of testing (unit tests, integration tests, UAT) and tools or frameworks you will use to ensure quality.</p></li><li><p><strong>Timeline and Milestones:</strong> Provide a clear project timeline with key milestones and deadlines, breaking the project into manageable phases or sprints.</p></li></ol><p>Make sure your solutions is broken down to subtasks that follow the SMART method (Specific, Measurable, Achievable, Relevant, Time-bound)</p><p>Once the Document is ready, you can share it with stakeholders where they will review, provide feedback, and be aligned on the approach. Once the solution is approved, you can move to the execution part.</p><h3><strong>Conclusion: Plan Smarter, Engineer Better</strong></h3><p>Engineering isn&#8217;t just about solving problems&#8212;it&#8217;s about solving the <em>right</em> problems effectively and building systems that endure. By following this six-step framework, you can become an engineer who creates meaningful, lasting impact.</p><h4><strong>Recap:</strong></h4><ol><li><p><strong>Understand the Problem</strong>: Start with 'Why' to ensure alignment with real needs.</p></li><li><p><strong>Collaborate and Align</strong>: Plan thoroughly and bring everyone on board.</p></li><li><p><strong>Break It Down</strong>: Translate high-level plans into actionable steps.</p></li><li><p><strong>Create the Design Document</strong>: Build systems that grow and adapt.</p></li></ol><p>Shift your mindset from <strong>output-focused</strong> to <strong>outcome-focused</strong> engineering. Start implementing these steps in your daily workflows today, and take the first step toward becoming a smarter, more effective engineer.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.effective-engineer.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Effective Engineering @ effective-engineer.com! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[How to Manage Sprint Tickets Like a Pro]]></title><description><![CDATA[Learn effective sprint ticket management strategies to prioritize tasks, streamline discussions, and achieve meaningful results in agile teams.]]></description><link>https://www.effective-engineer.com/p/cracking-the-code-how-to-manage-sprint</link><guid isPermaLink="false">https://www.effective-engineer.com/p/cracking-the-code-how-to-manage-sprint</guid><dc:creator><![CDATA[Effective Engineering]]></dc:creator><pubDate>Fri, 27 Dec 2024 06:03:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!aGk0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e6c0e2d-8826-4aca-978e-70eba2c04046_1600x1257.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!aGk0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e6c0e2d-8826-4aca-978e-70eba2c04046_1600x1257.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!aGk0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e6c0e2d-8826-4aca-978e-70eba2c04046_1600x1257.jpeg 424w, https://substackcdn.com/image/fetch/$s_!aGk0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e6c0e2d-8826-4aca-978e-70eba2c04046_1600x1257.jpeg 848w, https://substackcdn.com/image/fetch/$s_!aGk0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e6c0e2d-8826-4aca-978e-70eba2c04046_1600x1257.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!aGk0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e6c0e2d-8826-4aca-978e-70eba2c04046_1600x1257.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!aGk0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e6c0e2d-8826-4aca-978e-70eba2c04046_1600x1257.jpeg" width="1456" height="1144" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9e6c0e2d-8826-4aca-978e-70eba2c04046_1600x1257.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1144,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!aGk0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e6c0e2d-8826-4aca-978e-70eba2c04046_1600x1257.jpeg 424w, https://substackcdn.com/image/fetch/$s_!aGk0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e6c0e2d-8826-4aca-978e-70eba2c04046_1600x1257.jpeg 848w, https://substackcdn.com/image/fetch/$s_!aGk0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e6c0e2d-8826-4aca-978e-70eba2c04046_1600x1257.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!aGk0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e6c0e2d-8826-4aca-978e-70eba2c04046_1600x1257.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Effective sprint ticket management is the backbone of successful agile teams. Whether you&#8217;re a developer, or a team lead, how you handle tickets can determine whether your sprint delivers meaningful results or is it doomed for failure.</p><p>This guide explores strategies that will ensure success in sprint, it serves as a guide how to handle receiving and discussing tickets.</p><h4>Understanding the Role of Sprint Tickets</h4><p>Sprint tickets represent the granular tasks that collectively drive a project forward. However, they&#8217;re more than just to-do items. Each ticket embodies a slice of business value, and managing them well ensures that your efforts translate into tangible outcomes.</p><h4>Why Ticket Management Matters</h4><ul><li><p><strong>Maximizing Business Value:</strong> Ensuring the team focuses on tasks that align with organizational goals.</p></li><li><p><strong>Enhancing Team Productivity:</strong> Minimizing bottlenecks and confusion with clear, actionable tickets.</p></li><li><p><strong>Gaining Credibility:</strong> Meeting expectations by prioritizing tasks effectively and delivering consistently.</p></li></ul><h4>Effective Communication Around Tickets</h4><p>When a new ticket is introduced, the discussion around it sets the stage for success. Use these strategies to make kickoff conversations productive:</p><ol><li><p><strong>Ask Clarifying Questions:</strong> Ensure all ambiguities are resolved before work begins. For example: <em>&#8220;What is the desired outcome of this ticket?&#8221; , &#8220;Are there specific edge cases we need to account for?&#8221;</em></p></li><li><p><strong>Align on Acceptance Criteria:</strong> Define what &#8220;done&#8221; means. This avoids unnecessary rework.</p></li><li><p><strong>Identify Dependencies:</strong> Highlight upstream or downstream tasks that could impact completion.</p></li></ol><h4>Documenting for Clarity</h4><p>A well-documented ticket is a map, not a maze. Ensure tickets includes:</p><ul><li><p>A clear <strong>title</strong> summarizing the task</p></li><li><p>A concise <strong>description</strong> outlining the problem and context.</p></li><li><p><strong>Acceptance criteria</strong> that set expectations.</p></li><li><p><strong>Attachments or links</strong> to supporting documents.</p></li></ul><h4>How to Handle Edge Cases During Ticket Creation or Refinement</h4><p>Addressing edge cases early ensures robust implementation and reduces unforeseen blockers. Consider these practices:</p><ol><li><p><strong>Brainstorm Scenarios:</strong> Think through potential edge cases for the feature or bug fix.</p></li><li><p><strong>Collaborate with Stakeholders:</strong> Involve product managers, designers, and QA in identifying possible challenges.</p></li><li><p><strong>Document Clearly:</strong> Add explicit notes about edge cases in the ticket to guide implementation.</p></li></ol><h4>How to Size Tickets</h4><p>Proper ticket sizing is crucial for planning and execution. Here&#8217;s how to approach it:</p><ol><li><p><strong>Break Down Large Tasks:</strong> If a ticket seems too big, decompose it into smaller, manageable tasks.</p></li><li><p><strong>Follow the INVEST Principle:</strong> Ensure tickets are Independent, Negotiable, Valuable, Estimable, Small, and Testable.</p></li><li><p><strong>Use T-Shirt Sizes or Story Points:</strong> Categorize tasks as Small, Medium, or Large, or assign story points based on complexity and effort.</p></li><li><p><strong>Analyze dependencies:</strong> Identify whose work would be affected by this, what do you need from other teams or stakeholders to be able to deliver. This can be an API, a design, or a documentation.</p></li></ol><h4>How to Identify Dependencies</h4><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FHcx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd77b9a37-171e-4608-bbe3-8c078a99f775_1600x773.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FHcx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd77b9a37-171e-4608-bbe3-8c078a99f775_1600x773.png 424w, https://substackcdn.com/image/fetch/$s_!FHcx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd77b9a37-171e-4608-bbe3-8c078a99f775_1600x773.png 848w, https://substackcdn.com/image/fetch/$s_!FHcx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd77b9a37-171e-4608-bbe3-8c078a99f775_1600x773.png 1272w, https://substackcdn.com/image/fetch/$s_!FHcx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd77b9a37-171e-4608-bbe3-8c078a99f775_1600x773.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FHcx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd77b9a37-171e-4608-bbe3-8c078a99f775_1600x773.png" width="1456" height="703" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d77b9a37-171e-4608-bbe3-8c078a99f775_1600x773.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:703,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!FHcx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd77b9a37-171e-4608-bbe3-8c078a99f775_1600x773.png 424w, https://substackcdn.com/image/fetch/$s_!FHcx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd77b9a37-171e-4608-bbe3-8c078a99f775_1600x773.png 848w, https://substackcdn.com/image/fetch/$s_!FHcx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd77b9a37-171e-4608-bbe3-8c078a99f775_1600x773.png 1272w, https://substackcdn.com/image/fetch/$s_!FHcx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd77b9a37-171e-4608-bbe3-8c078a99f775_1600x773.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">RACI Matrix: used for clarifying dependencies, roles and responsibilities</figcaption></figure></div><p>Dependencies can make or break a sprint. Identifying them upfront prevents delays and bottlenecks.</p><ol><li><p><strong>Analyze Inputs and Outputs:</strong> Check if the ticket depends on the completion of another task or delivers something required by another.</p></li><li><p><strong>Consult Stakeholders:</strong> Discuss with other teams or individuals to uncover hidden dependencies.</p></li><li><p><strong>Use Visual Tools:</strong> Create dependency maps or annotate your board to highlight task relationships.</p></li><li><p><strong>Document Dependencies:</strong> Clearly note dependencies within the ticket to ensure visibility during planning.</p></li></ol><h4>How to Estimate Tickets</h4><p>Accurate estimation helps you set realistic goals and avoid overcommitment. Here are steps to improve estimation:</p><ol><li><p><strong>Understand the Scope:</strong> Ensure everyone involved understands the task&#8217;s requirements and acceptance criteria.</p></li><li><p><strong>Use Historical Data:</strong> Refer to similar tickets completed in the past to guide your estimates.</p></li><li><p><strong>Involve the Team:</strong> Engage the whole team in estimation discussions to benefit from everyone&#8217;s experience.</p></li><li><p><strong>Account for Risks:</strong> Add buffers for tasks with high uncertainty or external dependencies, or if it is ambiguous.</p></li><li><p><strong>Choose an Estimation Technique: Planning Poker:</strong> A collaborative approach to assigning story points. <strong>Bucket System:</strong> Group tickets into predefined buckets of complexity.</p></li></ol><p>When estimating, calculate an optimistic and a pessimistic estimation, and take the average.</p><p>For example let&#8217;s say the ticket will take 3 to 5 days to complete. You can communicate (3+5) days divided by 2 to take the average which is 4 days.</p><h4>Communicating risks and Uncertainties</h4><p>Uncertain tasks pose risks that can derail sprints. Handle these effectively:</p><ol><li><p><strong>Flag High-Risk Tickets:</strong> Clearly identify tickets with unknowns or technical challenges.</p></li><li><p><strong>Schedule Discovery Tickets:</strong> Use smaller exploratory tickets to research and reduce uncertainty.</p></li><li><p><strong>Document Findings:</strong> Share insights from discovery work to guide implementation.</p></li><li><p><strong>Add Buffers:</strong> Allocate extra time in your sprint for high-risk items.</p></li></ol><h4>Prioritization &amp; Negotiation: The Key to Delivering Impact</h4><p>Not all tickets are created equal. Effective prioritization ensures that the your efforts are directed where they matter most.</p><h4>Short-Term vs. Long-Term Goals</h4><p>Balancing urgent tasks with strategic objectives is an art. Here&#8217;s how to strike the right balance:</p><ul><li><p><strong>For Short-Term Wins:</strong> Focus on high-impact tasks that unblock other work.</p></li><li><p><strong>For Long-Term Success:</strong> Allocate time for technical debt, refactoring, and innovation.</p></li></ul><h4>Prioritization Frameworks: What should I pick first ?</h4><ol><li><p><strong>The Eisenhower Matrix: </strong>Urgent and Important: Address immediately. Important but Not Urgent: Schedule for later. Urgent but Not Important: Delegate if possible. Neither Urgent nor Important: Consider dropping.</p></li><li><p><strong>Weighted Scoring:</strong> Assign scores based on factors like business value, effort, and risk.</p></li><li><p><strong>WSJF (Weighted Shortest Job First):</strong> Calculate priority by dividing value by effort, ensuring the team tackles high-impact, low-effort tasks first.</p></li></ol><h4>Clear Ownership and Responsibility for Every Ticket</h4><p>Ownership is critical to ensure accountability and progress. Here&#8217;s how to assign and manage it:</p><ol><li><p><strong>Define Roles:</strong> Clarify who needs to provide input, review, or approve the task.</p></li><li><p><strong>Follow up:</strong> Continuously align with people you need to work with to deliver, Ask for updates, and progress.</p></li><li><p><strong>Be transparent</strong>: Continuously update your stakeholders on progress, blockers, and issues that could impact your delivery. If a change is needed in estimation, communicate it as soon as possible.</p></li></ol><h4>Technical Feasibility Discussions</h4><p>Technical feasibility is a cornerstone of ticket management. Ensure alignment with these steps:</p><ol><li><p><strong>Review with your team:</strong> Conduct feasibility discussions during refinement sessions.</p></li><li><p><strong>Align with Architecture:</strong> Validate that the solution fits within the existing technical architecture.</p></li><li><p><strong>Assess Tooling:</strong> Confirm that the necessary tools and libraries are available and adequate.</p></li><li><p><strong>Document Constraints:</strong> Capture any limitations discovered during your discussions.</p></li></ol><h3>Managing Stakeholder&#8217;s Expectations</h3><h4>Setting Realistic Timelines</h4><p>Stakeholders often want everything done yesterday. Managing their expectations requires transparency:</p><ul><li><p><strong>Explain Trade-offs:</strong> Highlight what can&#8217;t be done if a specific task is prioritized.</p></li><li><p><strong>Provide Data:</strong> Use metrics like velocity and cycle time to justify timelines.</p></li><li><p><strong>Offer Alternatives:</strong> Suggest phased rollouts for complex tasks.</p></li></ul><h4>Communicating Delays</h4><p>Delays are inevitable. The key is how you communicate them:</p><ul><li><p><strong>Be Proactive:</strong> Inform stakeholders as soon as risks emerge.</p></li><li><p><strong>Focus on Solutions:</strong> Highlight what&#8217;s being done to get back on track.</p></li><li><p><strong>Reaffirm Value:</strong> Emphasize the importance of quality over rushing.</p></li></ul><h4>Collaboration for Better Ticket Management</h4><p>Effective ticket prioritization often requires input from multiple stakeholders. To align everyone:</p><ul><li><p><strong>Facilitate Discussions:</strong> Use sprint planning or backlog refinement meetings to reach agreements.</p></li><li><p><strong>Visualize Priorities:</strong> Use tools like Kanban boards to make trade-offs visible.</p></li><li><p><strong>Document Decisions:</strong> Record why certain tickets were prioritized to avoid future disputes.</p></li></ul><h4>Leveraging Tools</h4><p>Modern tools can transform how teams manage tickets:</p><ul><li><p><strong>JIRA:</strong> A robust platform for tracking tickets and visualizing workflows.</p></li><li><p><strong>Trello:</strong> Simple boards for lightweight ticket management.</p></li><li><p><strong>Linear:</strong> Streamlined ticketing for modern product teams.</p></li></ul><h4>Common Pitfalls</h4><p><strong>Avoid overloading the Sprint </strong>packing too many tickets into a sprint leads to unfinished work. Do not over commit.</p><p><strong>Avoid Ignoring Technical Debt</strong>: Prioritizing only new features while neglecting technical debt creates long-term issues. Allocate a percentage of each sprint for debt repayment.</p><p><strong>Avoid Lack of Clear Ownership: </strong>When no one owns a ticket, it gets lost. Assign clear owners for each task and hold them accountable.</p><h4>Key Takeaways</h4><ol><li><p><strong>Communication is Key:</strong> Start every ticket discussion by clarifying goals, requirements, and dependencies.</p></li><li><p><strong>Prioritize for Impact:</strong> Use frameworks like WSJF and the Eisenhower Matrix to balance short-term urgency with long-term goals.</p></li><li><p><strong>Align Stakeholders:</strong> Manage expectations with transparency and data-driven decisions.</p></li><li><p><strong>Leverage Tools:</strong> Platforms like JIRA and Trello can streamline workflows and improve visibility.</p></li><li><p><strong>Avoid Overloading:</strong> Focus on achievable sprints, technical debt, and clear ownership.</p></li><li><p><strong>Size and Estimate Effectively:</strong> Break tasks into manageable sizes, identify dependencies, and use team-driven estimation techniques.</p></li><li><p><strong>Plan for Uncertainty:</strong> Use discovery tickets and buffers for high-risk tasks.</p></li><li><p><strong>Review Feasibility:</strong> Align tickets with technical architecture and tooling requirements.</p></li></ol>]]></content:encoded></item><item><title><![CDATA[4 steps to dealing with workplace conflict]]></title><description><![CDATA[Learn how to manage conflict with your manager, rebuild trust, and restore a professional relationship after tense situations or mistakes.]]></description><link>https://www.effective-engineer.com/p/4-steps-to-dealing-with-workplace</link><guid isPermaLink="false">https://www.effective-engineer.com/p/4-steps-to-dealing-with-workplace</guid><dc:creator><![CDATA[Effective Engineering]]></dc:creator><pubDate>Wed, 25 Dec 2024 06:13:53 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!mBLU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f98ef6d-2702-4658-ad11-767c90d5b941_1400x788.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mBLU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f98ef6d-2702-4658-ad11-767c90d5b941_1400x788.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mBLU!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f98ef6d-2702-4658-ad11-767c90d5b941_1400x788.jpeg 424w, https://substackcdn.com/image/fetch/$s_!mBLU!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f98ef6d-2702-4658-ad11-767c90d5b941_1400x788.jpeg 848w, https://substackcdn.com/image/fetch/$s_!mBLU!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f98ef6d-2702-4658-ad11-767c90d5b941_1400x788.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!mBLU!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f98ef6d-2702-4658-ad11-767c90d5b941_1400x788.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mBLU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f98ef6d-2702-4658-ad11-767c90d5b941_1400x788.jpeg" width="1400" height="788" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6f98ef6d-2702-4658-ad11-767c90d5b941_1400x788.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:788,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!mBLU!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f98ef6d-2702-4658-ad11-767c90d5b941_1400x788.jpeg 424w, https://substackcdn.com/image/fetch/$s_!mBLU!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f98ef6d-2702-4658-ad11-767c90d5b941_1400x788.jpeg 848w, https://substackcdn.com/image/fetch/$s_!mBLU!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f98ef6d-2702-4658-ad11-767c90d5b941_1400x788.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!mBLU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f98ef6d-2702-4658-ad11-767c90d5b941_1400x788.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@javaistan?utm_source=medium&amp;utm_medium=referral">Afif Ramdhasuma</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure></div><p>Conflict with your manager happen. Sometimes, things get out of control, it could be a tense one-on-one, or a mistake that damages trust. These situations are challenging, but they&#8217;re not irreparable.</p><p>Here&#8217;s a 4-step framework for repairing damaged relationship with your manager:</p><h2><strong>Step 1: Own Your Mistakes</strong></h2><p>The first step in resolving conflict is to own responsibility for your actions. Acknowledge where you went wrong and apologize sincerely, without making excuses. For example:<br>&#8220;I handled this poorly.&#8221;<br>&#8220;I&#8217;m committed to fixing our relationship and ensuring this doesn&#8217;t happen again.&#8221;</p><p>From there, shift the conversation toward solutions. Ask, &#8220;How can we fix this together?&#8221; Work wit your manager to agree on clear next steps, make sure you document them to prevent misunderstandings and ensure accountability, as it is the foundation for rebuilding trust.</p><h2><strong>Step 2: Focus on Adding Value</strong></h2><p>Once you&#8217;ve acknowledged your mistakes, let your actions do the talking. Re-establishing trust requires consistent effort. Focus on:<br>Delivering high-quality work.<br>Sharing updates proactively and documenting your progress.<br>Aligning your efforts with team goals to demonstrate reliability.</p><p>Consistency over time proves that you&#8217;re serious about rebuilding trust and adds tangible value to the relationship.</p><h2><strong>Step 3: Be Patient</strong></h2><p>Trust is not rebuilt overnight. It takes time and repeated positive interactions to restore credibility. Be patient with the process, even if it feels slow.<br>Every delivered result, constructive interaction, and demonstrated improvement is a step forward. Stay consistent, and the relationship will gradually improve.</p><h2><strong>Step 4: Follow Up</strong></h2><p>Resolution doesn&#8217;t end with a single conversation. Regular check-ins show that you&#8217;re committed to maintaining and strengthening the relationship. Use these opportunities to:<br>Ask for feedback on how things are improving.<br>Reaffirm your dedication to the relationship and team goals.</p><p>Follow-ups demonstrate your investment in long-term success, not just short-term fixes.</p><h2><strong>Final Thoughts</strong></h2><p>Relationships may not always return to what they were, but with effort and persistence, you can rebuild credibility and move forward stronger than before.</p><p>Sometimes, despite your best efforts, the relationship remains strained or the environment becomes untenable. In these cases, it&#8217;s okay to move on. Prioritize your well-being and growth over staying in a toxic or irreparable situation.</p><p>Walking away isn&#8217;t a failure; it&#8217;s a recognition that some situations cannot be fixed. It&#8217;s better to focus your energy on opportunities that align with your values and aspirations.<br>What strategies have worked for you when handling workplace conflict? Share your insights in the comments!</p>]]></content:encoded></item><item><title><![CDATA[Why Some Software Engineers Become Great (And Others Stay Good)]]></title><description><![CDATA[When I first started leading teams, I tried to observe what made a great software engineer.]]></description><link>https://www.effective-engineer.com/p/why-some-software-engineers-become-great-and-others-stay-good-30f0ec202dc9</link><guid isPermaLink="false">https://www.effective-engineer.com/p/why-some-software-engineers-become-great-and-others-stay-good-30f0ec202dc9</guid><dc:creator><![CDATA[Effective Engineering]]></dc:creator><pubDate>Sun, 22 Dec 2024 12:24:12 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/5af589ad-4d9a-4c67-99b9-3d8a0d7a3267_2600x1733.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MIJT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23b3a56a-57e9-43bc-b9ae-a1ff32b4fbc5_1400x933.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MIJT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23b3a56a-57e9-43bc-b9ae-a1ff32b4fbc5_1400x933.jpeg 424w, https://substackcdn.com/image/fetch/$s_!MIJT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23b3a56a-57e9-43bc-b9ae-a1ff32b4fbc5_1400x933.jpeg 848w, https://substackcdn.com/image/fetch/$s_!MIJT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23b3a56a-57e9-43bc-b9ae-a1ff32b4fbc5_1400x933.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!MIJT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23b3a56a-57e9-43bc-b9ae-a1ff32b4fbc5_1400x933.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MIJT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23b3a56a-57e9-43bc-b9ae-a1ff32b4fbc5_1400x933.jpeg" width="1400" height="933" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/23b3a56a-57e9-43bc-b9ae-a1ff32b4fbc5_1400x933.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:933,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!MIJT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23b3a56a-57e9-43bc-b9ae-a1ff32b4fbc5_1400x933.jpeg 424w, https://substackcdn.com/image/fetch/$s_!MIJT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23b3a56a-57e9-43bc-b9ae-a1ff32b4fbc5_1400x933.jpeg 848w, https://substackcdn.com/image/fetch/$s_!MIJT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23b3a56a-57e9-43bc-b9ae-a1ff32b4fbc5_1400x933.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!MIJT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23b3a56a-57e9-43bc-b9ae-a1ff32b4fbc5_1400x933.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@austinchan?utm_source=medium&amp;utm_medium=referral">Austin Chan</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure></div><p>When I first started leading teams, I tried to observe what made a great software engineer. What characteristics should I focus on while mentoring to help my team level up? I came across many observations. In this article, I am highlighting the common skills I found in great engineers I have known throughout my career.</p><h2><strong>The Outcome-Oriented Engineer</strong></h2><p>A good engineer focuses on meeting requirements, writing code, and delivering functionality. While these tasks are important, they don&#8217;t always address the core question:</p><p><strong>Does this work create value?</strong></p><p>Great engineers, on the other hand, look beyond the immediate deliverable and consider the broader impact. They ask:</p><ul><li><p>Why does this feature matter to the user?</p></li><li><p>How does it align with business goals?</p></li></ul><p>They view their role not just as problem-solvers but as value creators. These engineers are always curious to understand the problem they are solving beyond the minimum required to deliver the ticket. This curiosity drives great engineers to observe their stakeholders, understand their needs and pain points, and contribute by designing systems and creating solutions that address these challenges.</p><p>What makes great engineers stand out is their customer-centric approach. Whether serving internal customers like product managers and quality assurance teams, or focusing on end users, they always consider the broader impact of their work. Their curiosity to understand the problem they are solving, paired with technical expertise, drives their ability to add value and be outcome-driven engineers.</p><blockquote><p><em>&#8220;We&#8217;re not competitor-obsessed, we&#8217;re customer-obsessed. We start with what the customer needs and we work backwards.&#8221;<br>&#8212; Jeff Bezos</em></p></blockquote><p>At Amazon, the concept of &#8220;two-pizza teams&#8221; exemplifies this mindset. These small, autonomous groups are structured to ensure accountability and ownership over entire projects. For example, the team responsible for Amazon Prime Video tracks metrics like video streaming quality, playback speed, and user retention, integrating these metrics with technical aspects such as performance and downtime. By focusing on outcomes, engineers ensure their work aligns with business objectives and enhances customer satisfaction.</p><h2><strong>Looking at the big picture</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!NttB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3192ddb0-bcd9-4981-a508-7a999a547e02_1400x933.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!NttB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3192ddb0-bcd9-4981-a508-7a999a547e02_1400x933.jpeg 424w, https://substackcdn.com/image/fetch/$s_!NttB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3192ddb0-bcd9-4981-a508-7a999a547e02_1400x933.jpeg 848w, https://substackcdn.com/image/fetch/$s_!NttB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3192ddb0-bcd9-4981-a508-7a999a547e02_1400x933.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!NttB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3192ddb0-bcd9-4981-a508-7a999a547e02_1400x933.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!NttB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3192ddb0-bcd9-4981-a508-7a999a547e02_1400x933.jpeg" width="1400" height="933" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3192ddb0-bcd9-4981-a508-7a999a547e02_1400x933.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:933,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!NttB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3192ddb0-bcd9-4981-a508-7a999a547e02_1400x933.jpeg 424w, https://substackcdn.com/image/fetch/$s_!NttB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3192ddb0-bcd9-4981-a508-7a999a547e02_1400x933.jpeg 848w, https://substackcdn.com/image/fetch/$s_!NttB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3192ddb0-bcd9-4981-a508-7a999a547e02_1400x933.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!NttB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3192ddb0-bcd9-4981-a508-7a999a547e02_1400x933.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@232_038t?utm_source=medium&amp;utm_medium=referral">Thorium</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure></div><p>Great engineers think about problems in terms of the system as a whole. They know that no component of a system stands alone and realize that to create scalable, maintainable solutions, they need to consider how each part interacts with other systems.</p><p>System thinking is at the heart of this approach, where the focus shifts from optimizing isolated features to ensuring that the system, in its entirety, will work seamlessly &#8212; even while growing or changing.</p><p>I remember when I started working as an engineer, I was often focused on solving the immediate problem in front of me &#8212; fixing a bug or optimizing a feature. As I gained more experience, I realized that this approach was not enough. The more I worked with complex systems, the more I understood how individual parts are interconnected, amplifying or reducing issues across the system. It was then that I understood how important it is to think of how each component works together as part of a cohesive whole to build something truly scalable and maintainable.</p><p>Netflix invested in this concept by introducing Chaos Engineering, which pushes system thinking to the next level. They introduced tools like Chaos Monkey, which purposely triggers failures in their systems, simulating real-world disruptions. This kind of stress testing has made Netflix&#8217;s architecture remarkably resilient. It pushed their engineers to think: <em>How will my change react to surprises and unexpected scenarios?</em></p><p>Looking at the big picture doesn&#8217;t just apply to technical solution design. It also means being adaptive to change and understanding the broader vision.</p><h2><strong>Adapt and Anticipate</strong></h2><p>In 2008, Netflix faced a major database corruption that prevented them from shipping DVDs to customers for several days. This experience led them to realize they needed to migrate from using their own data centers to AWS.</p><p>The migration took seven years to complete. They could have moved their data centers directly to Amazon as-is, cutting down effort and time. Instead, they anticipated the need for future scalability and rebuilt their infrastructure to support the scale they now operate at, which is ten times the size it was in 2008.</p><p>Great engineers know that problems never exist in isolation. They focus on the bigger picture and the impact of every part of the system &#8212; how they relate and how to prioritize efforts based on the system&#8217;s needs. It&#8217;s about designing for resilience, scalability, and flexibility. Building solutions that not only work now but can adapt as the system evolves.</p><p>Whether developing a product, scaling architecture, or leading a team, this way of thinking makes the difference between a mediocre product and a great one. A great engineer owns the product and understands that combining technical expertise with soft skills and collaboration allows them to influence engineering excellence.</p><h2><strong>Collaboration and Influence: The Multiplier Effect</strong></h2><p>Engineering isn&#8217;t a solo pursuit.</p><p>The best engineers understand that great things happen when they collaborate. They don&#8217;t just write code in isolation; they connect with teammates, share ideas, and build trust to create amazing products.</p><p>Great engineers lead without a title but with influence. Instead of relying on hierarchy, they guide the team by encouraging open communication, sharing insights, and ensuring alignment on the same goal. They build trust by being approachable, inclusive, and credible. They share knowledge and help others without blame or judgment.</p><h2><strong>Psychological Safety in Teams</strong></h2><p>The impact of these traits is significant &#8212; they strongly affect overall team performance by increasing psychological safety. This was proven in Google&#8217;s research, which found that psychological safety is the foundation for great teams. This is why these engineers are indispensable; their multiplier effect enhances their peers and stakeholders alike.</p><p>This is why it&#8217;s essential to engage in constant communication. Regularly check in with your teammates &#8212; whether they&#8217;re engineers, designers, or product managers. Make sure you are moving in the same direction. The more you share, the clearer the collective vision becomes. When you work closely with others, you create a stronger, more unified approach to solving problems.</p><p>Whenever possible, talk to your colleagues in other roles regularly. Ask questions, share challenges, and collaborate to align on priorities. This ensures everyone is on the same page and avoids miscommunication that could derail progress.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!QjPM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d9eace2-8410-47ad-9148-e8bb93f03de0_1394x1358.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QjPM!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d9eace2-8410-47ad-9148-e8bb93f03de0_1394x1358.png 424w, https://substackcdn.com/image/fetch/$s_!QjPM!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d9eace2-8410-47ad-9148-e8bb93f03de0_1394x1358.png 848w, https://substackcdn.com/image/fetch/$s_!QjPM!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d9eace2-8410-47ad-9148-e8bb93f03de0_1394x1358.png 1272w, https://substackcdn.com/image/fetch/$s_!QjPM!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d9eace2-8410-47ad-9148-e8bb93f03de0_1394x1358.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QjPM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d9eace2-8410-47ad-9148-e8bb93f03de0_1394x1358.png" width="1394" height="1358" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5d9eace2-8410-47ad-9148-e8bb93f03de0_1394x1358.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1358,&quot;width&quot;:1394,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!QjPM!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d9eace2-8410-47ad-9148-e8bb93f03de0_1394x1358.png 424w, https://substackcdn.com/image/fetch/$s_!QjPM!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d9eace2-8410-47ad-9148-e8bb93f03de0_1394x1358.png 848w, https://substackcdn.com/image/fetch/$s_!QjPM!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d9eace2-8410-47ad-9148-e8bb93f03de0_1394x1358.png 1272w, https://substackcdn.com/image/fetch/$s_!QjPM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d9eace2-8410-47ad-9148-e8bb93f03de0_1394x1358.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Psychological safety in the teams</figcaption></figure></div><h2><strong>Conclusion</strong></h2><p>Engineers should adopt the traits discussed above by asking the right questions and building meaningful connections with their teams and stakeholders. This will not only elevate their own capabilities and keep them motivated as they add value, but also make them indispensable to their teams.</p><h1><strong>TL;DR:</strong></h1><ul><li><p><strong>Collaborate effectively:</strong> Build trust, communicate openly, and foster psychological safety within your team. Diverse perspectives lead to better solutions.</p></li><li><p><strong>Deliver measurable value:</strong> Go beyond shipping features &#8212; focus on solving real problems and ensuring your work creates meaningful impact.</p></li><li><p><strong>Adopt system thinking:</strong> Design scalable, resilient systems that consider future growth and the interconnectedness of all components.</p></li><li><p><strong>Be outcome-oriented:</strong> Align your work with business goals and user needs, ensuring it delivers tangible results.</p></li></ul><p>&#128073; <a href="http://www.effective-engineer.com/">Checkout my blog</a><br>&#128038; <a href="https://x.com/EffectiveEng">Follow me on X</a></p>]]></content:encoded></item><item><title><![CDATA[Move Fast Without Breaking Things !]]></title><description><![CDATA[How to Deliver Fast and maintain quality, through Refactoring, Feature Flags, and Automation]]></description><link>https://www.effective-engineer.com/p/move-fast-without-breaking-things-5ec7478e017a</link><guid isPermaLink="false">https://www.effective-engineer.com/p/move-fast-without-breaking-things-5ec7478e017a</guid><dc:creator><![CDATA[Effective Engineering]]></dc:creator><pubDate>Thu, 19 Dec 2024 09:06:31 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/ef45b565-969f-47d3-9430-69771aec8e14_1024x1024.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fQ4d!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F624b7e58-f4d3-43bc-b1c1-8a92d89d4167_1024x1024.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fQ4d!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F624b7e58-f4d3-43bc-b1c1-8a92d89d4167_1024x1024.jpeg 424w, https://substackcdn.com/image/fetch/$s_!fQ4d!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F624b7e58-f4d3-43bc-b1c1-8a92d89d4167_1024x1024.jpeg 848w, https://substackcdn.com/image/fetch/$s_!fQ4d!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F624b7e58-f4d3-43bc-b1c1-8a92d89d4167_1024x1024.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!fQ4d!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F624b7e58-f4d3-43bc-b1c1-8a92d89d4167_1024x1024.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fQ4d!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F624b7e58-f4d3-43bc-b1c1-8a92d89d4167_1024x1024.jpeg" width="1024" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/624b7e58-f4d3-43bc-b1c1-8a92d89d4167_1024x1024.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!fQ4d!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F624b7e58-f4d3-43bc-b1c1-8a92d89d4167_1024x1024.jpeg 424w, https://substackcdn.com/image/fetch/$s_!fQ4d!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F624b7e58-f4d3-43bc-b1c1-8a92d89d4167_1024x1024.jpeg 848w, https://substackcdn.com/image/fetch/$s_!fQ4d!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F624b7e58-f4d3-43bc-b1c1-8a92d89d4167_1024x1024.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!fQ4d!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F624b7e58-f4d3-43bc-b1c1-8a92d89d4167_1024x1024.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">A tug of war between speed and quality</figcaption></figure></div><p>Every software engineer knows the drill. A new feature request lands on your desk with a deadline that feels like it was set yesterday. You roll up your sleeves, knowing that delivering on time might mean cutting corners &#8212; skipping tests, hardcoding a value, or hacking together a quick fix. It feels great when the feature goes live, but weeks later, when the bug reports flood in, you wonder: was moving fast worth breaking things?</p><p>The reality is that engineering is a constant tug-of-war between speed and quality. Move too fast, and you build a house of cards that collapses at the worst time. Focus too much on perfection, and you risk being labeled &#8220;too slow.&#8221; But here&#8217;s the thing: speed and quality aren&#8217;t opposites. You don&#8217;t have to choose one over the other. Let&#8217;s dive into how you can move fast <em>and</em> build maintainable systems that won&#8217;t come back to haunt you.</p><p><strong>Why &#8220;Move Fast and Break Things&#8221; Doesn&#8217;t Work</strong></p><p>&#8220;Move fast and break things&#8221; became the go to philosophy for innovation during the startup boom. But for anyone who has worked on a live production system, this philosophy often feels like a disaster waiting to happen.</p><p>I have worked at a startup where the default was to ship fast. I once did a hotfix to show a loading indicator in a page no one uses. Adopting this philosophy means you are turning away from solving problems and becoming a feature factory with no consideration of data. After a while, we ended up with a product that always had bugs, very hard to fix, and slow to add features to. Our focus became to get what&#8217;s on production to run, with time we lost purpose and that was our only focus. The startup went bankrupt.</p><p>A more sustainable approach that could have saved the company would have been to prioritize long-term velocity. High-quality code may take slightly longer to ship, but it pays off by reducing the time spent fixing bugs, cleaning up spaghetti code, or firefighting in production.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ViRL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62a80d87-2f6d-4fa5-af1b-06732acc2ab8_1024x1024.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ViRL!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62a80d87-2f6d-4fa5-af1b-06732acc2ab8_1024x1024.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ViRL!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62a80d87-2f6d-4fa5-af1b-06732acc2ab8_1024x1024.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ViRL!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62a80d87-2f6d-4fa5-af1b-06732acc2ab8_1024x1024.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ViRL!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62a80d87-2f6d-4fa5-af1b-06732acc2ab8_1024x1024.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ViRL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62a80d87-2f6d-4fa5-af1b-06732acc2ab8_1024x1024.jpeg" width="1024" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/62a80d87-2f6d-4fa5-af1b-06732acc2ab8_1024x1024.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!ViRL!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62a80d87-2f6d-4fa5-af1b-06732acc2ab8_1024x1024.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ViRL!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62a80d87-2f6d-4fa5-af1b-06732acc2ab8_1024x1024.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ViRL!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62a80d87-2f6d-4fa5-af1b-06732acc2ab8_1024x1024.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ViRL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62a80d87-2f6d-4fa5-af1b-06732acc2ab8_1024x1024.jpeg 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Hell and heaven comparison between quick fixes and refactored code</figcaption></figure></div><p><strong>Plan for Refactoring From the Start</strong></p><p>Here&#8217;s a truth every engineer needs to embrace: shortcuts are inevitable. Deadlines, pivots, and last-minute changes happen, and sometimes you need to cut corners to deliver on time. The problem isn&#8217;t taking shortcuts &#8212; it&#8217;s treating them as permanent.</p><p>To balance speed with quality, start with the mindset that every shortcut is temporary. Log these quick fixes as tech debt tasks in your backlog, and prioritize them like you would a new feature. When planning sprints, allocate time to clean up code.</p><p>Think of it like writing a to-do list. If you borrowed code from Stack Overflow to hit a deadline, make sure to revisit it later and implement a proper solution. Engineers who plan for refactoring from day one build systems that evolve gracefully instead of breaking down. From my experience , agreeing with product managers on 10% of sprint velocity for refactoring is reasonable and would help maintain the codebase quality.</p><p><strong>Focus on Containing the Mess</strong></p><p>If you have to cut corners, make sure the mess doesn&#8217;t spread. When writing quick fixes or hacks, isolate them within specific modules, components, or files.</p><p>For instance, if you&#8217;re hardcoding a value for a quick demo, keep it in a clearly labeled config file or a single function. This makes it easier to find and replace later. The key is to keep these shortcuts localized, so they don&#8217;t become landmines scattered across your codebase.</p><p>One of my former teammates called this &#8220;putting the mess in a drawer.&#8221; It&#8217;s still there, but at least you know where to find it.</p><p>I follow the same approach for A/B tests, as there is a chance we will remove them if the test failed. I try to keep them isolated for easy cleanup and less affected area when we do. I would recommend doing the same for urgent requests. It will make refactoring much faster, and less likely to break things.</p><p><strong>Feature Flags for Safe Iteration</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!aRHO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98cbbfd9-b337-469b-af75-9f9e16b37759_1024x1024.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!aRHO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98cbbfd9-b337-469b-af75-9f9e16b37759_1024x1024.jpeg 424w, https://substackcdn.com/image/fetch/$s_!aRHO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98cbbfd9-b337-469b-af75-9f9e16b37759_1024x1024.jpeg 848w, https://substackcdn.com/image/fetch/$s_!aRHO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98cbbfd9-b337-469b-af75-9f9e16b37759_1024x1024.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!aRHO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98cbbfd9-b337-469b-af75-9f9e16b37759_1024x1024.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!aRHO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98cbbfd9-b337-469b-af75-9f9e16b37759_1024x1024.jpeg" width="1024" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/98cbbfd9-b337-469b-af75-9f9e16b37759_1024x1024.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!aRHO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98cbbfd9-b337-469b-af75-9f9e16b37759_1024x1024.jpeg 424w, https://substackcdn.com/image/fetch/$s_!aRHO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98cbbfd9-b337-469b-af75-9f9e16b37759_1024x1024.jpeg 848w, https://substackcdn.com/image/fetch/$s_!aRHO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98cbbfd9-b337-469b-af75-9f9e16b37759_1024x1024.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!aRHO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98cbbfd9-b337-469b-af75-9f9e16b37759_1024x1024.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Feature flags dashboard</figcaption></figure></div><p>Feature flags are a game-changer when you need to ship fast without sacrificing quality. By wrapping new features in a flag, you can deploy unfinished work to production safely. This lets you test with a small group of users, gather feedback, and iterate without risking the entire system.</p><p>For example, if you&#8217;re rolling out a new search feature, a feature flag allows you to enable it for 5% of users while monitoring performance. If something goes wrong, you can turn it off instantly without needing a rollback.</p><p>Feature flags give you the freedom to experiment without turning your production environment into a testing ground.</p><p><strong>Automate Testing and Use CI/CD Pipelines</strong></p><p>Nothing kills speed like regressions. You&#8217;ve shipped a feature, moved on to the next task, and suddenly, an old bug reappears. Now you&#8217;re stuck fixing it instead of building something new.</p><p>Automated tests and CI/CD pipelines are your best defense against this chaos. integration tests ensure modules play nicely together, and end-to-end tests validate user workflows.</p><p>Think of these as a safety net. They might take time to set up, but they let you move quickly without fear of breaking things. Plus, they make you look like a rockstar when you catch a bug before it reaches production.</p><p>Manual Regressions from QA can take a day or 2 for them to be done properly, without automation a lot of corners will be cut when a request is urgent causing a domino effect of bugs and hotfixes</p><p><strong>Dedicate Time for Refactoring (Refactoring Fridays)</strong></p><p>One of the simplest ways to balance speed and quality is to schedule time for maintenance.We discussed the 10% block. I experimented with that by introducing &#8220;Refactoring Fridays&#8221; &#8212; a day dedicated to paying down technical debt. No feature work, no distractions &#8212; just pure cleanup.</p><p>This practice worked wonders. Developers looked forward to Fridays because it gave them the breathing room to tidy up messy code and fix things they&#8217;d been meaning to address. The result? A healthier codebase and a happier team.</p><p>We did not dedicate the entire day but each engineer blocked a couple of hours in their calendar to clean up.</p><p>We also had another practice where we did mob programming as a team once a month for an hour to refactor a part in the system. This increased collaboration, team morale and our code base health.</p><p><strong>Set Clear Priorities with Stakeholders</strong></p><p>Engineers often face pressure from stakeholders to deliver faster. But here&#8217;s a pro tip: speed and quality don&#8217;t have to be at odds if you communicate effectively.</p><p>When discussing timelines with stakeholders, explain the trade-offs of cutting corners. For example:</p><p>&#8220;We can deliver this feature in two weeks, but to meet that deadline, we&#8217;ll take some shortcuts that will require cleanup later. Alternatively, we can spend an extra week building it properly, which will save us time in the long run.&#8221;</p><p>By framing the conversation around business outcomes (e.g., reduced risk, better performance), you can gain stakeholder buy-in for balanced timelines.</p><p><strong>Speed and Quality Are Not Opposites</strong></p><p>Balancing speed and quality isn&#8217;t just possible &#8212; it&#8217;s essential for sustainable development. By planning for refactoring, isolating quick fixes, leveraging feature flags, and automating tests, you can deliver fast without sacrificing maintainability.</p><p>Remember, moving fast doesn&#8217;t mean rushing blindly. It means being intentional about where you take shortcuts and having a plan to address them. So the next time you&#8217;re tempted to just &#8220;get it done,&#8221; take a moment to think long-term.</p><p>Fast doesn&#8217;t have to mean messy. Quality doesn&#8217;t have to mean slow. With the right practices, you can have both &#8212; and become the kind of engineer everyone wants on their team.</p><p>Have you found ways to balance speed and quality in your projects? I&#8217;d love to hear your strategies &#8212; drop them in the comments below!</p><p><em>Enjoyed this article?</em> Follow me for more insights on becoming an <strong>Effective Engineer.</strong></p><p><br>&#128038; <a href="https://x.com/EffectiveEng">Follow me on X</a></p>]]></content:encoded></item><item><title><![CDATA[Distributed Systems: Key Concepts]]></title><description><![CDATA[Modern software systems rarely operate in isolation.]]></description><link>https://www.effective-engineer.com/p/distributed-systems-key-concepts-8b399241ca15</link><guid isPermaLink="false">https://www.effective-engineer.com/p/distributed-systems-key-concepts-8b399241ca15</guid><dc:creator><![CDATA[Effective Engineering]]></dc:creator><pubDate>Wed, 18 Dec 2024 07:17:23 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/9708c5cd-67fd-4a6d-861e-2e827bbef485_660x460.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Modern software systems rarely operate in isolation. Whether you&#8217;re scaling a web app, handling massive datasets, or ensuring uptime, <strong>distributed systems</strong> play a critical role. But how can engineers design systems that are reliable, fast, and fault-tolerant?</p><p>This guide breaks down the essential concepts of distributed systems&#8202;&#8212;&#8202;stripped of heavy theory&#8202;&#8212;&#8202;and connects them to practical, real-world scenarios.</p><p><strong>What Are Distributed Systems (and Why Do Engineers Need&nbsp;Them)?</strong></p><p>A <strong>distributed system</strong> is a set of computers working together as one unit. This setup helps engineers:</p><ul><li><p><strong>Scale horizontally</strong> (e.g., adding more machines to handle traffic).</p></li><li><p><strong>Handle failures gracefully</strong> (e.g., replicating data across multiple&nbsp;nodes).</p></li><li><p><strong>Ensure high performance</strong> (e.g., optimizing for low-latency access).</p></li></ul><p>A typical e-commerce platform relies&nbsp;on:</p><ul><li><p>Compute instances behind a load balancer.</p></li><li><p>A relational database for transactional data.</p></li><li><p>Durable file storage replicated across&nbsp;regions.</p></li></ul><ol><li><p><strong>Fault Tolerance: Preparing for&nbsp;Failures</strong></p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4a5M!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74e251a4-fe26-4f63-83cd-0c588159d785_660x460.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4a5M!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74e251a4-fe26-4f63-83cd-0c588159d785_660x460.jpeg 424w, https://substackcdn.com/image/fetch/$s_!4a5M!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74e251a4-fe26-4f63-83cd-0c588159d785_660x460.jpeg 848w, https://substackcdn.com/image/fetch/$s_!4a5M!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74e251a4-fe26-4f63-83cd-0c588159d785_660x460.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!4a5M!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74e251a4-fe26-4f63-83cd-0c588159d785_660x460.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4a5M!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74e251a4-fe26-4f63-83cd-0c588159d785_660x460.jpeg" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/74e251a4-fe26-4f63-83cd-0c588159d785_660x460.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!4a5M!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74e251a4-fe26-4f63-83cd-0c588159d785_660x460.jpeg 424w, https://substackcdn.com/image/fetch/$s_!4a5M!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74e251a4-fe26-4f63-83cd-0c588159d785_660x460.jpeg 848w, https://substackcdn.com/image/fetch/$s_!4a5M!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74e251a4-fe26-4f63-83cd-0c588159d785_660x460.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!4a5M!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74e251a4-fe26-4f63-83cd-0c588159d785_660x460.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a><figcaption class="image-caption">Failover illustration</figcaption></figure></div><p>In distributed systems, failures (server crashes, network partitions, etc.) are inevitable. Systems must continue running without disruption.</p><p><strong>Strategies for Fault Tolerance:</strong></p><ul><li><p><strong>Data Replication:</strong> Store copies of data across multiple nodes to ensure durability.</p></li><li><p><strong>Health Checks and Failover:</strong> Replace unhealthy nodes and reroute traffic to healthy&nbsp;ones.</p></li><li><p><strong>Monitoring and Recovery:</strong> Detect errors and trigger automatic recovery&nbsp;actions.</p></li></ul><p><strong>Real-World Example:</strong> During a data center outage, services can maintain access by replicating data across multiple locations. For instance, a streaming service might rely on alarms to trigger scaling or failover processes, keeping the stream uninterrupted.</p><p><strong>2. Balancing Consistency and Availability (CAP&nbsp;Theorem)</strong></p><p>The <strong>CAP theorem</strong> states that distributed systems can only optimize for <strong>two out of three properties</strong>:</p><ul><li><p><strong>Consistency:</strong> All nodes return the latest&nbsp;data.</p></li><li><p><strong>Availability:</strong> Every request receives a response, even during failures.</p></li><li><p><strong>Partition Tolerance:</strong> The system continues operating despite network failures.</p></li></ul><p>Because <strong>network partitions</strong> are unavoidable, you must choose between <strong>consistency</strong> and <strong>availability</strong> depending on the use&nbsp;case.</p><p><strong>Examples:</strong></p><ul><li><p><strong>Eventual Consistency: IoT Data Ingestion:</strong> High-volume sensor data can tolerate slight delays in propagating updates to all replicas. <strong>Content Delivery:</strong> Product catalogs or social media feeds where slight delays are acceptable.</p></li><li><p><strong>Strong Consistency: Healthcare Systems</strong> ensures accurate patient records during concurrent updates. <strong>Order Processing</strong> Guarantees that inventory is updated immediately to prevent overselling.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gw-0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97872234-3435-474a-9673-61f5e67df5f9_736x700.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gw-0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97872234-3435-474a-9673-61f5e67df5f9_736x700.png 424w, https://substackcdn.com/image/fetch/$s_!gw-0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97872234-3435-474a-9673-61f5e67df5f9_736x700.png 848w, https://substackcdn.com/image/fetch/$s_!gw-0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97872234-3435-474a-9673-61f5e67df5f9_736x700.png 1272w, https://substackcdn.com/image/fetch/$s_!gw-0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97872234-3435-474a-9673-61f5e67df5f9_736x700.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gw-0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97872234-3435-474a-9673-61f5e67df5f9_736x700.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/97872234-3435-474a-9673-61f5e67df5f9_736x700.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!gw-0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97872234-3435-474a-9673-61f5e67df5f9_736x700.png 424w, https://substackcdn.com/image/fetch/$s_!gw-0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97872234-3435-474a-9673-61f5e67df5f9_736x700.png 848w, https://substackcdn.com/image/fetch/$s_!gw-0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97872234-3435-474a-9673-61f5e67df5f9_736x700.png 1272w, https://substackcdn.com/image/fetch/$s_!gw-0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97872234-3435-474a-9673-61f5e67df5f9_736x700.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">An illustration that highlights CAP&nbsp;theorem</figcaption></figure></div><p><strong>3. Transactions in Distributed Systems</strong></p><p>Distributed systems often need to handle <strong>transactions</strong>&#8202;&#8212;&#8202;groups of operations that must succeed or fail together but ensuring atomicity, consistency, isolation, and durability (<strong>ACID</strong>) across distributed nodes is challenging.</p><p><strong>Common Approaches:</strong></p><ol><li><p><strong>Relational Databases:</strong> Offer ACID guarantees for transactional systems like banking or inventory management.</p></li><li><p><strong>NoSQL Databases with Transactions:</strong> Allow multi-item, ACID-compliant transactions for use cases like transferring funds.</p></li></ol><p><strong>Example:</strong> Imagine a payment app. When transferring funds, you need&nbsp;to:</p><ul><li><p>Deduct the amount from one&nbsp;account.</p></li><li><p>Add it to another&nbsp;account.</p></li></ul><p>Distributed transactions ensure <strong>atomicity</strong>&#8202;&#8212;&#8202;both updates succeed or fail together.</p><p><strong>Challenges:</strong></p><ul><li><p><strong>Throughput Constraints:</strong> Transactions can introduce bottlenecks under high&nbsp;loads.</p></li><li><p><strong>Scalability:</strong> Limited to a specific number of items or data size in some&nbsp;systems.</p></li></ul><p><strong>Simplifying Distributed Transactions: </strong>Traditional distributed systems used techniques like <strong>2-Phase Commit (2PC)</strong> to ensure node consistency. Modern solutions abstract this complexity with managed transaction support, making it easier for engineers to build reliable&nbsp;systems.</p><p><strong>Pro Tip:</strong> Use <strong>idempotent retries</strong> to handle network failures during transactions without introducing duplicates or inconsistencies.</p><p><strong>Concrete Example:</strong> Consider a distributed order processing system. If a network failure occurs after an inventory reduction, retry logic ensures the inventory reduction is not repeated.</p><p><strong>4. Scaling</strong></p><p>Scaling distributed systems is about increasing capacity by adding machines (<strong>horizontal scaling</strong>) while maintaining performance.</p><p><strong>Techniques for&nbsp;Scaling:</strong></p><ul><li><p><strong>Dynamic Scaling:</strong> Automatically add or remove resources based on&nbsp;demand.</p></li><li><p><strong>Read Replicas:</strong> Scale database reads by adding replicas.</p></li><li><p><strong>Serverless Scaling:</strong> Tools like serverless functions (e.g., AWS Lambda) reduce operational overhead by automatically handling resource scaling for event-driven systems. This is particularly useful for workflows like image processing or real-time notifications.</p></li></ul><p>For a global chat application:</p><ul><li><p>Replicate user messages across regions to ensure low-latency access.</p></li><li><p>Use caching for frequently accessed messages.</p></li><li><p>Scale message processing workflows dynamically during peak&nbsp;loads.</p></li></ul><p><strong>Multi-Region Benefits:</strong></p><ul><li><p><strong>Latency Reduction:</strong> Replicate data closer to users in different regions.</p></li><li><p><strong>Disaster Recovery:</strong> Provide redundancy so traffic can failover during&nbsp;outages.</p></li></ul><p><strong>Key Takeaways</strong></p><p>To build reliable, scalable distributed systems:</p><ol><li><p>Use <strong>RPC</strong> for inter-service communication and handle&nbsp;retries.</p></li><li><p>Design for <strong>fault tolerance</strong> with strategies like data replication and failover.</p></li><li><p>Balance <strong>consistency</strong> and <strong>availability</strong> based on your use&nbsp;case.</p></li><li><p>Handle <strong>distributed transactions</strong> with relational or NoSQL databases.</p></li><li><p>Scale your system horizontally with dynamic scaling, replicas, caching, and serverless workflows.</p></li></ol><p>Distributed systems are complex, but the principles remain universal. Focus on designing systems that embrace failures, balance consistency vs availability, and scale effortlessly to meet user&nbsp;demands.</p><p><em>Enjoyed this article?</em> Follow me for more insights on becoming an <strong>Effective Engineer.</strong></p><p>&#128073; <a href="https://effective-eng.medium.com/">Follow me on Medium</a><br>&#128038; <a href="https://x.com/EffectiveEng">Follow me on&nbsp;X</a></p>]]></content:encoded></item><item><title><![CDATA[Beyond Code: The Pursuit of Technical Excellence]]></title><description><![CDATA[In the world of software engineering, technical excellence is often misunderstood.]]></description><link>https://www.effective-engineer.com/p/beyond-code-the-pursuit-of-technical-excellence-0430cecdcd15</link><guid isPermaLink="false">https://www.effective-engineer.com/p/beyond-code-the-pursuit-of-technical-excellence-0430cecdcd15</guid><dc:creator><![CDATA[Effective Engineering]]></dc:creator><pubDate>Tue, 17 Dec 2024 06:31:05 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/efcb7f64-caba-4136-99ce-c8e069d39184_800x800.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the world of software engineering, technical excellence is often misunderstood. Many see it as simply writing perfect code, adopting the newest tech stack, or achieving flawless execution. But these views miss the mark. For example, a team might focus on clean code without considering its relevance to the business outcome, or chase the latest tools at the cost of stability. True technical excellence is about making deliberate choices&#8202;&#8212;&#8202;balancing innovation with practicality, and ensuring that systems are well-built, impactful, and sustainable.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XiTN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0463872-35f1-43de-95f0-2c565ae85264_800x800.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XiTN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0463872-35f1-43de-95f0-2c565ae85264_800x800.jpeg 424w, https://substackcdn.com/image/fetch/$s_!XiTN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0463872-35f1-43de-95f0-2c565ae85264_800x800.jpeg 848w, https://substackcdn.com/image/fetch/$s_!XiTN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0463872-35f1-43de-95f0-2c565ae85264_800x800.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!XiTN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0463872-35f1-43de-95f0-2c565ae85264_800x800.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XiTN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0463872-35f1-43de-95f0-2c565ae85264_800x800.jpeg" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d0463872-35f1-43de-95f0-2c565ae85264_800x800.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!XiTN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0463872-35f1-43de-95f0-2c565ae85264_800x800.jpeg 424w, https://substackcdn.com/image/fetch/$s_!XiTN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0463872-35f1-43de-95f0-2c565ae85264_800x800.jpeg 848w, https://substackcdn.com/image/fetch/$s_!XiTN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0463872-35f1-43de-95f0-2c565ae85264_800x800.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!XiTN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd0463872-35f1-43de-95f0-2c565ae85264_800x800.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a><figcaption class="image-caption">Building Systems that&nbsp;scale</figcaption></figure></div><p>So, what does it take to achieve technical excellence?</p><p>Great engineers recognize that speed and quality aren&#8217;t at odds&#8202;&#8212;&#8202;they complement each other when approached thoughtfully. For example, a team might prioritize delivering an MVP quickly but still apply solid engineering practices, such as writing modular, testable code. This allows them to iterate rapidly without accumulating excessive technical debt, ensuring that early speed doesn&#8217;t compromise long-term stability. When speed and quality align, teams can move fast while laying a strong foundation for future&nbsp;growth.</p><p>Technical excellence goes beyond writing good code&#8202;&#8212;&#8202;it involves building systems that last, navigating trade-offs thoughtfully, and owning outcomes beyond the immediate task. It requires a mindset that values long-term sustainability, craftsmanship, and the ability to adapt when the constraints of reality come into&nbsp;play.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!IrcJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30b06db3-1fc0-469f-94e9-6f65070cb3d0_800x800.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!IrcJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30b06db3-1fc0-469f-94e9-6f65070cb3d0_800x800.jpeg 424w, https://substackcdn.com/image/fetch/$s_!IrcJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30b06db3-1fc0-469f-94e9-6f65070cb3d0_800x800.jpeg 848w, https://substackcdn.com/image/fetch/$s_!IrcJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30b06db3-1fc0-469f-94e9-6f65070cb3d0_800x800.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!IrcJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30b06db3-1fc0-469f-94e9-6f65070cb3d0_800x800.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!IrcJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30b06db3-1fc0-469f-94e9-6f65070cb3d0_800x800.jpeg" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/30b06db3-1fc0-469f-94e9-6f65070cb3d0_800x800.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!IrcJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30b06db3-1fc0-469f-94e9-6f65070cb3d0_800x800.jpeg 424w, https://substackcdn.com/image/fetch/$s_!IrcJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30b06db3-1fc0-469f-94e9-6f65070cb3d0_800x800.jpeg 848w, https://substackcdn.com/image/fetch/$s_!IrcJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30b06db3-1fc0-469f-94e9-6f65070cb3d0_800x800.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!IrcJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30b06db3-1fc0-469f-94e9-6f65070cb3d0_800x800.jpeg 1456w" sizes="100vw"></picture><div></div></div></a><figcaption class="image-caption">Balancing between speed and&nbsp;quality</figcaption></figure></div><p>This series will explore the core pillars of technical excellence:</p><ol><li><p><strong>Balancing Speed and Quality</strong>: Learn to deliver results quickly without sacrificing maintainability or creating&nbsp;chaos.</p></li><li><p><strong>Building Systems That Last</strong>: Explore how to design systems with maintainability, scalability, and resilience in mind, ensuring they stand the test of&nbsp;time.</p></li><li><p><strong>Measuring and Managing Technical Debt</strong>: Understand how to identify, quantify, and address technical debt so it doesn&#8217;t cripple your team in the&nbsp;future.</p></li><li><p><strong>Navigating Trade-offs</strong>: Gain strategies for making thoughtful decisions when you&#8217;re working with limited time, resources, or competing priorities.</p></li><li><p><strong>Craftsmanship and Ownership</strong>: Discover the importance of owning outcomes, prioritizing engineering quality, and building with a sense of pride and accountability.</p></li></ol><p>Each article will provide actionable advice, real-world examples, and practical frameworks&#8202;&#8212;&#8202;like strategies for managing technical debt, workflows for balancing speed and quality, and case studies of scalable system design&#8202;&#8212;&#8202;to help you build systems that stand the test of time while delivering value to your team and organization.</p><p>Technical excellence isn&#8217;t a destination&#8202;&#8212;&#8202;it&#8217;s a journey. Along the way, you&#8217;ll sharpen your craft, drive meaningful impact, and inspire those around you to aim higher. By embracing technical excellence, you won&#8217;t just build better systems&#8202;&#8212;&#8202;you&#8217;ll become a better engineer. Let&#8217;s get&nbsp;started.</p><p><strong>Follow me here or on X at <a href="https://x.com/EffectiveEng">The Effective Engineer</a> to keep up with the&nbsp;series</strong></p>]]></content:encoded></item><item><title><![CDATA[AI’s Impact on Engineering: Why the Right Skills Matter More Than Ever]]></title><description><![CDATA[In the traditional engineering view, the focus has often been on technical expertise.]]></description><link>https://www.effective-engineer.com/p/ais-impact-on-engineering-why-the-right-skills-matter-more-than-ever-931ad168e1e1</link><guid isPermaLink="false">https://www.effective-engineer.com/p/ais-impact-on-engineering-why-the-right-skills-matter-more-than-ever-931ad168e1e1</guid><dc:creator><![CDATA[Effective Engineering]]></dc:creator><pubDate>Sun, 15 Dec 2024 10:37:26 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/961c0808-450f-4590-9048-f3bfd3728320_1024x683.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pppH!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0b3d16b-7ad9-43f7-a301-34eb9fe44c61_1024x683.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pppH!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0b3d16b-7ad9-43f7-a301-34eb9fe44c61_1024x683.jpeg 424w, https://substackcdn.com/image/fetch/$s_!pppH!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0b3d16b-7ad9-43f7-a301-34eb9fe44c61_1024x683.jpeg 848w, https://substackcdn.com/image/fetch/$s_!pppH!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0b3d16b-7ad9-43f7-a301-34eb9fe44c61_1024x683.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!pppH!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0b3d16b-7ad9-43f7-a301-34eb9fe44c61_1024x683.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pppH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0b3d16b-7ad9-43f7-a301-34eb9fe44c61_1024x683.jpeg" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a0b3d16b-7ad9-43f7-a301-34eb9fe44c61_1024x683.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!pppH!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0b3d16b-7ad9-43f7-a301-34eb9fe44c61_1024x683.jpeg 424w, https://substackcdn.com/image/fetch/$s_!pppH!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0b3d16b-7ad9-43f7-a301-34eb9fe44c61_1024x683.jpeg 848w, https://substackcdn.com/image/fetch/$s_!pppH!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0b3d16b-7ad9-43f7-a301-34eb9fe44c61_1024x683.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!pppH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0b3d16b-7ad9-43f7-a301-34eb9fe44c61_1024x683.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><p>In the traditional engineering view, the focus has often been on technical expertise. From university courses to online tutorials, the emphasis is on mastering programming languages, understanding complex algorithms, and working with data structures. While these skills are undeniably valuable, they represent only one piece of the puzzle for today&#8217;s engineers.</p><p>In light of the growing influence of AI in the tech industry, this article challenges the conventional narrative of what it means to be a successful engineer. As AI reshapes the landscape, engineering success demands more than technical competence. It requires an approach that considers the broader ecosystem in which software operates. The role of engineers is expanding beyond coding to include critical areas such as product ownership, collaboration, and understanding the impact of their work. In this evolving landscape, engineers must adapt and embrace the intersection of technical skills and team impact to&nbsp;thrive.</p><p>In this article, we aim to challenge the conventional narrative. True engineering success extends far beyond simply knowing how to code or grasping the intricacies of algorithms.</p><p>This perspective shift takes us into three crucial areas that define engineering excellence:</p><h3>1. Technical Excellence</h3><p>At its core, engineering demands a solid foundation in technical principles. A deep understanding of fundamental computer science concepts&#8202;&#8212;&#8202;data structures, algorithms, software design patterns&#8202;&#8212;&#8202;is essential. Engineers need proficiency in programming languages, whether object-oriented or functional, as well as a clear understanding of system architecture, ensuring different components interact seamlessly in scalable and maintainable systems.</p><p>However, in today&#8217;s world, technical excellence goes beyond just coding proficiency. It&#8217;s about continuously learning, staying up-to-date with emerging technologies and methodologies, and dedicating oneself to writing clean, efficient, and well-documented code. Embracing best practices like unit testing, code reviews, and continuous integration helps ensure the codebase remains robust, adaptable, and maintainable.</p><h3>2. Product Ownership</h3><p>In today&#8217;s fast-paced, user-centric world, engineers need to be more than just code producers&#8202;&#8212;&#8202;they must become product owners. This means they need to understand the underlying business objectives and the needs of the users. Engineers must shift from a task-oriented mindset to a product-focused approach.</p><p>Active participation in product discussions with product managers, designers, and other stakeholders is key. Engineers must understand user needs, define product requirements, and translate those needs into effective technical solutions. A strong grasp of user experience (UX) principles is essential, as engineers strive to build products that are not only technically sound but also intuitive and user-friendly.</p><p>Moreover, successful engineers track the impact of their work by defining and monitoring key performance indicators (KPIs). This allows them to make data-driven decisions, prioritize efforts effectively, and continuously enhance their contributions.</p><h3>3. Collaboration &amp; Influence</h3><p>Engineering is inherently collaborative. Successful projects almost always result from the effective interplay of diverse skills and perspectives. This part of engineering is about more than just technical output&#8202;&#8212;&#8202;it&#8217;s about relationships, influence, and building a positive, productive environment.</p><h4>Building Strong Relationships</h4><ul><li><p><strong>Effective Communication</strong>: Clear, concise communication of technical concepts to both technical and non-technical audiences is essential. Whether it&#8217;s explaining complex systems to stakeholders or writing documentation, strong communication skills are a&nbsp;must.</p></li><li><p><strong>Active Listening</strong>: Listening to understand others&#8217; perspectives fosters empathy and builds stronger relationships.</p></li><li><p><strong>Cross-Functional Collaboration</strong>: Engineers need to work effectively with various teams&#8202;&#8212;&#8202;product managers, designers, and marketers&#8202;&#8212;&#8202;ensuring that everyone is aligned and any conflicts are resolved.</p></li></ul><h4>Leading and Influencing Without a&nbsp;Title</h4><ul><li><p><strong>Mentorship &amp; Guidance</strong>: Supporting junior engineers, sharing knowledge, and fostering a learning culture strengthens the team as a&nbsp;whole.</p></li><li><p><strong>Driving Positive Change</strong>: Engineers should take the initiative to improve processes, increase efficiency, and raise team&nbsp;morale.</p></li><li><p><strong>Building a Strong Engineering Culture</strong>: Contributing to a team culture that values collaboration, innovation, and a shared sense of purpose can have a lasting&nbsp;impact.</p></li></ul><h3>Expanding Your Impact: From Implementation to Influence</h3><p>The traditional image of an engineer is often that of a lone coder, focused solely on writing code. While this picture still holds some truth, it misses the broader role that engineers play today. The journey from being a proficient coder to an outcome-driven engineer involves a fundamental shift:</p><ul><li><p><strong>From Task-Oriented to Product-Oriented</strong>: Engineers need to engage in product discussions, understand strategic goals, and prioritize their work based on potential impact.</p></li><li><p><strong>From Individual Contributor to Team Player</strong>: Engineers should contribute to creating a positive team environment, share knowledge, mentor others, and collaborate effectively with cross-functional teams.</p></li><li><p><strong>From Code Producer to Problem Solver</strong>: Engineers should focus on solving real-world problems rather than just writing code. They must design solutions that meet user needs, address business challenges, and drive innovation.</p></li><li><p><strong>From Technical Specialist to Business Partner</strong>: Engineers should understand the business context of their work and communicate technical implications to both technical and non-technical stakeholders.</p></li></ul><p>This shift is ongoing. It requires continuous learning, stepping outside of one&#8217;s comfort zone, and a commitment to personal growth. The engineers who thrive today are those who embrace these transformations and actively seek opportunities to expand their skills and influence.</p><p>By embracing this engineering approach&#8202;&#8212;&#8202;technical excellence, product ownership, and collaboration&#8202;&#8212;&#8202;engineers can unlock their full potential. They can move beyond just writing code and become indispensable contributors to their teams and the broader tech ecosystem.</p>]]></content:encoded></item></channel></rss>