Writing · Tales of Engineering Leadership
Speed Through Quality
The counterintuitive case that slowing down to do it well is the fastest way to ship.
In my years as an Engineering Leader, I’ve often seen teams race to deliver features, only to later grapple with bugs, technical debt, and escalating customer support issues. It’s a frustrating paradox: in the rush for speed, teams sometimes cut corners that would have enabled faster, smoother progress down the line. But what if embracing quality could actually accelerate development?
By adopting key principles that may initially seem counterintuitive—like deploying multiple times per day, limiting work in progress, or avoiding feature branching—teams can streamline their workflows, enhance product quality, and make development more enjoyable. These practices reinforce each other, creating a synergy that boosts both speed and quality.
In the following sections, I’ll share experiences and insights from my journey in leading teams to embrace speed through quality. I’ll explore how prioritizing quality has transformed the way teams work, resulting in a faster and more predictable delivery pace without compromising on the product delivered.
I’ll save for a following post the common pitfalls that might show along the way and how to overcome them.

Build the Right Thing
The journey starts by building empowered teams. Inspired by the Team Topologies1 model, it’s paramount to streamline team structures, creating focused, cross-functional groups that own distinct areas of responsibility. By aligning each team around a specific business domain, organizations can reduce dependencies, simplify communication, and increase accountability. When teams are empowered to make decisions and take ownership of their work, they become more agile and responsive to both user needs and changing market demands.
Next step should be to coach the teams around a customer-first mindset—a real commitment to understanding what users need. In a fast-moving market where preferences and pressures shift rapidly, building software that addresses real-world problems means staying close to customers at every stage. This moves beyond a one-time requirements gathering exercise to an ongoing process of validating user needs throughout development.
Effective teams iterate and validate quickly with customers. By connecting through interviews, surveys, usability tests, and early releases, they gather insights to refine features and reveal unexpected needs. Real-time feedback keeps development aligned with actual user needs, enabling early adjustments and avoiding costly rework. This approach, grounded in Lean Software Development principles from Poppendieck2 and Ries3, focuses on reducing waste and emphasizing validated learning.
Short, iterative cycles enable continuous refinement based on direct user feedback. Each release—whether a small feature or early prototype—brings new insights, feeding into the next phase. This build, measure, learn cycle keeps teams agile and responsive to evolving user needs, providing a real edge in staying competitive.
Fast feedback loops also unify the team—engineering, design, and product management—ensuring alignment and adaptability as more insights emerge. By routinely validating customer needs, teams create a shared vision across the organization, keeping everyone focused on impactful outcomes.
A customer-centered approach minimizes wasted effort on features that don’t add value, ensuring the product roadmap stays focused on what truly matters. Instead of spending months building extensive functionality that may miss the mark, high-performing teams prioritize incremental value delivery. Each iteration moves the product closer to meeting real customer needs, avoiding “feature bloat” that clutters the user experience and complicates the codebase.
In the following sections, we’ll explore the practices and principles that make iterative, user-focused development both achievable and sustainable.
Build the Thing Right
To enable quick adaptation based on feedback, teams rely on a set of development practices that reinforce each other, creating a feedback loop that accelerates the entire process. Without these practices, adapting to real user feedback becomes much more challenging.
Work-In-Progress (WIP) Limits: Streamlining Focus for Greater Quality
WIP limits help teams maintain steady progress by capping the number of active tasks, ensuring that features aren’t left in limbo and reducing context-switching. By focusing on fewer items at a time, teams increase throughput, improve quality, and shorten cycle times, leading to faster iteration and clearer visibility into task completion. This focus prevents the accumulation of partially finished work that can clutter workflows and drain momentum.
WIP limits also create a more sustainable pace, allowing team members to fully engage with each task rather than juggling multiple priorities. By setting clear boundaries on work in progress, teams stay agile and responsive, consistently delivering value and avoiding bottlenecks that could stall the pipeline. Over time, this practice fosters a culture of discipline and quality, where the emphasis is on completing and refining work, rather than simply starting new tasks.
Test Automation and TDD (Test-Driven Development)
A major turning point for teams I’ve worked with was adopting Test Automation, especially through Test-Driven Development (TDD). Though it may seem counterintuitive at first, TDD fundamentally shifts how engineers approach code.
In practice, TDD involves writing a test that defines the desired outcome for a specific piece of functionality. Only then the minimal amount of code required to pass that test is written. This process continues iteratively, with each test guiding the development of the next small piece of functionality. Once the code passes the test, it’s refactored to ensure it’s as simple and efficient as possible. Kent Beck, in Test-Driven Development: By Example (2002)4, points out that TDD is as much about design as it is about testing, forcing engineers to build code that’s easy to test and leading to cleaner, modular designs.
Building an automated test suite that runs continuously during development provides immediate feedback in the developer’s environment, helping to catch issues early and avoid committing code that breaks existing functionality. Integrating these tests into the Continuous Integration (CI) pipeline—and prioritizing prompt fixes for any pipeline failures—keeps the codebase always deployable and ensures rapid feedback before deployment. This fast feedback is invaluable because it allows teams to catch issues early. And because TDD encourages to write only enough code to pass the tests, teams end up with simpler, more focused codebase that’s easier to maintain and understand.
In summary, some of the immediate benefits I’ve seen from Test Automation and TDD include:
-
Fast Feedback: Automated tests provide instant feedback on code correctness, allowing quick identification and resolution of issues.
-
Faster Iterations: Testing small pieces of functionality breaks complex problems into manageable steps, making development systematic and efficient.
-
Better Architecture: Designing for testability naturally results in modular, decoupled systems, making the codebase easier to maintain and scale.
-
Avoiding Over-Engineering: TDD keeps us focused on what’s needed to pass tests, avoiding unnecessary features and maintaining simplicity.
-
Easier Adaptation: A well-tested, streamlined codebase is easier to modify, enabling quick adjustments as conditions evolve.
-
Confidence to Refactor: With solid test coverage, we can refactor confidently, verifying functionality with minimal risk.
-
Documentation: A well-constructed test suite serves as living documentation, always current and reflective of the code’s actual behavior.
Next level collaboration: Trunk-Based Development and Pair Programming
To support quick iterations and feedback loops, teams should also adopt trunk-based development. This approach has all developers working on a single shared branch, or “trunk,” with frequent commits—often multiple times daily. Continuous integration into a single branch reduces the risk of long-lived feature branches diverging and causing complex merge conflicts. By committing frequently and in small increments, issues are easier to isolate and revert, thanks to the smaller scope of changes.
Pair programming enhances collaboration, with two developers working together on the same code. While it might seem slower—two people on one task—the benefits are significant:
-
Immediate Code Review: With two sets of eyes, errors and bad practices are caught right away, making the feedback loop immediate and reducing the chance of defects reaching production.
-
Knowledge Sharing: Pairing enables developers to learn from each other, minimizing knowledge silos and creating a more resilient, versatile team.
-
Shared Ownership and Team Cohesion: Working together strengthens responsibility and commitment, connecting team members to both the codebase and user needs, boosting morale and a culture of accountability.
Extreme Programming (XP) principles, as championed by Kent Beck5, emphasize immediate feedback and shared knowledge. Pair programming embodies these principles, helping teams tackle complex problems more effectively and reducing bugs in production. Together, TDD, trunk-based development, and pair programming create a foundation for a high-quality development process that’s resilient, flexible, and deeply collaborative.
Continuous Improvement: Continuous Learning and the Boy Scout Rule
A commitment to continuous learning and improvement is essential for effective development teams. In an industry where technologies, best practices, and user expectations evolve constantly, standing still isn’t an option. High-performing teams seek to improve not only their codebase but also their processes, team dynamics, and individual skills, ensuring both the team and the software continually adapt and improve.
A guiding principle here is the Boy Scout Rule: “leave the campground cleaner than you found it.” Applied to software, this means every time a developer touches code, they aim to make it a bit better—whether by renaming variables for clarity, breaking up large functions, removing unused code, etc.. These small, incremental improvements keep the codebase healthy, maintainable, and easier to work with over time.
By adopting the Boy Scout Rule, teams actively combat technical debt. Rather than allowing inefficiencies, ambiguities, and outdated structures to accumulate, they address them as part of the regular workflow. This approach fosters a sense of craftsmanship and ownership, where developers take pride in the quality of their contributions. It also creates a proactive culture, where the team not only addresses issues as they arise but prevents them by consistently maintaining high code quality standards.
Continuous Refactoring and the Importance of Incremental Improvements Instead of viewing refactoring as a large, daunting task, effective teams treat it as a natural part of daily development. Incremental improvements are made along the way, with developers refining code whenever they spot areas that could be clearer, simpler, or more efficient. These small changes compound over time, resulting in a cleaner, more organized codebase without the need for major overhauls.
For projects with legacy code, the Boy Scout Rule proves especially valuable. Legacy code often has years of technical debt and minimal documentation, making large-scale rewrites risky. Successful teams focus on incremental refactoring, yielding substantial benefits: a more readable, less error-prone codebase that’s easier for new team members to onboard with and for existing developers to work in. Over time, this approach creates a more sustainable system, ready for future development.
Fostering a Culture of Continuous Learning Continuous improvement goes beyond code; it’s about building a team that’s always learning. Growth-focused teams encourage curiosity and promote learning through training, workshops, conferences, and experimenting with new tools and techniques. Regular retrospectives are also key, offering a space to reflect on what’s working, what isn’t, and how to adapt moving forward.
By fostering a culture of continuous learning, teams remain adaptable and resilient. Developers feel empowered to improve not only the code they write but also the ways they work, collaborate, and solve problems. This focus on growth creates a positive feedback loop where individual learning contributes to team improvement, which in turn creates a sustainable, resilient foundation for long-term success, leading to a better product and greater user satisfaction.
Deployment Automation: Closing the loop
Observability as a First-Class Citizen For modern development teams, observability is essential for monitoring system performance and proactively identifying issues. A strong observability framework offers real-time insights into application health and behavior, providing transparency that’s crucial for stability—especially when iterating rapidly and rolling out new features frequently.
Observability covers logging, metrics, and tracing, each serving a unique role in understanding application behavior. Clear observability practices allow teams to catch issues before they affect users, enabling faster diagnosis and resolution. This visibility also helps teams understand user interactions, revealing patterns and performance bottlenecks that aren’t immediately obvious. When prioritized in the development process, observability minimizes surprises, reduces downtime, and ensures a reliable user experience, opening the doors for a more dynamic deployment process.
Feature Toggles: Decoupling Deployment from Release Incorporating feature toggles into development gives teams greater control over when and how new functionality is made available to users. A feature toggle allows code to be deployed to production without activating the new functionality for all users, decoupling deployment from feature release. This flexibility supports controlled testing in a production environment and gradual feature rollouts, effectively managing risk.
Feature toggles are particularly useful for A/B testing, releasing features to a subset of users based on certain criteria. With rapid rollback capability, feature toggles provide a safety net, allowing teams to disable a feature instantly if issues arise. As Peter Hodgson highlights in Feature Toggles (aka Feature Flags)6, they act as a bridge, enabling real-time agility to respond to user feedback.
Deployment Automation: Ensuring Consistent, Reliable Releases For effective teams, deployment automation has transformed the way they delivery software. Manual deployments are often error-prone and stressful, especially under tight deadlines or during off-hours. Automating the deployment process replaces these manual steps with consistent, repeatable procedures, ensuring each deployment is reliable across environments.
Automated deployment systems define the exact steps for deploying an application, executing them precisely every time. Tools like Docker and Kubernetes allow applications to be containerized with all dependencies, creating a standardized environment that behaves the same in development, staging, and production. This approach eliminates the “works on my machine” issue, ensuring code functions as expected wherever it’s deployed. As noted by Duvall et al.7, deployment automation is key to maintaining stability and efficiency in modern development.
Together, observability, feature flags, and deployment automation create the foundation for continuous deployment. Observability provides the real-time visibility needed to identify and address issues as they arise, ensuring that deployments don’t introduce unexpected disruptions. Feature flags allow teams to release updates safely, testing in production with specific user groups and rolling back instantly if needed—decoupling the act of deploying from the decision to activate new features. Deployment automation ensures that releases are consistent and reliable, eliminating manual errors and enabling frequent, low-stress deployments.
Continuous deployment alongside the other practices we’ve discussed, has a measurable impact on DORA metrics as defined in Accelerate by Forsgren, Humble, and Kim8, which gauge software delivery performance:
-
Deployment Frequency: Automated deployment enables teams to release code as soon as it passes tests, significantly increasing deployment frequency and allowing multiple daily releases without manual bottlenecks.
-
Lead Time for Changes: Automation shortens the path from code commit to deployment. With pipelines managing each step from testing to release, teams experience reduced lead times for changes.
-
Mean Time to Recovery (MTTR): Automated rollback capabilities reduce MTTR when production issues occur. Rapid reversion to a stable version enables quicker incident response, minimizing user impact.
-
Change Failure Rate: Consistent, automated deployments lower error risk, reducing the change failure rate. By standardizing deployment, human error is minimized, leading to fewer production issues.
Conclusion: Quality as the Key to Speed
The journey toward achieving “speed through quality” has redefined effective software development. For high-performing teams, quality isn’t a barrier to speed—it drives it. By embedding practices that enable quick iterations, teams deliver faster without compromising stability or user satisfaction. Prioritizing quality leads to a better product and transforms the development process into one that’s more efficient, resilient, and rewarding.
The benefits of a quality-driven approach are both tangible and far-reaching:
-
Accelerated Development: With strong feedback loops, streamlined processes, and automated testing, teams identify and address issues early, enabling faster delivery with confidence.
-
Higher Quality Software: Proactive measures like TDD, continuous integration, and continuous deployment reduce bugs and technical debt, creating a stable, reliable experience that builds user satisfaction and trust.
-
Stronger Teams: Collaborative practices, such as pair programming, continuous learning, and retrospectives, foster resilience and teamwork. Developers feel more connected to their work, resulting in a motivated and engaged team.
-
Greater Business Value: Rapid, reliable releases keep teams competitive and responsive to customer needs, directly enhancing the ability to meet market demands and seize new opportunities.
By embracing these principles, teams ensure they’re building the right product—and building it right. This approach enables organizations to adapt to a changing world, one small release at a time.
Footnotes
-
Skelton, M., & Pais, M. (2019) Team Topologies: Organizing Business and Technology Teams for Fast Flow. IT Revolution Press, . ↩
-
Poppendieck, M. & Poppendieck, T. (2003). Lean Software Development: An Agile Toolkit. Addison-Wesley Professional. ↩
-
Ries, E. (2011). The Lean Startup. Crown Business. ↩
-
Beck, K. (2002). Test-Driven Development: By Example. Addison-Wesley Professional. ↩
-
Beck, K. (2004). Extreme Programming Explained: Embrace Change. Addison-Wesley Professional. ↩
-
Hodgson, P. (2017). Feature Toggles (aka Feature Flags) - https://martinfowler.com/articles/feature-toggles.html ↩
-
Duval et al. (2007). Continuous Integration: Improving Software Quality and Reducing Risk. Addison-Wesley Professional. ↩
-
Forsgren, Humble, and Kim (2018) Accelerate: The Science of Lean Software and DevOps: Building and Scaling High Performing Technology Organizations. IT Revolution Press. ↩