On Code Quality and Velocity

A letter from a Seasoned CTO to a team lead struggling with delivery pace

Dear Rising Team Lead,

Your message about the challenges your team faces—high standards but slow delivery, elegant code but features that never quite reach production—struck a familiar chord. The tension between quality and velocity is perhaps the most fundamental balancing act in our profession, one I've wrestled with throughout my career.

First, let me affirm something: your commitment to quality is admirable. In an industry where "move fast and break things" can sometimes become an excuse for carelessness, your concern for craftsmanship sets you apart. Never lose that. But as someone who once found myself leading a team that produced beautiful code at a glacial pace, I want to share some hard-won perspective on finding a healthier balance.

The uncomfortable reality is this: nothing counts unless it reaches production. The most elegantly architected solution, the most performant algorithm, the most maintainable codebase—none of these matter if they never serve actual users. I had to learn this lesson the hard way when, after six months of "perfecting" a system, we discovered our requirements had fundamentally changed, rendering much of our careful work irrelevant.

This doesn't mean that quality doesn't matter—quite the contrary. But it does mean we need to redefine what quality actually means. True quality isn't just about clean code; it's about code that delivers value, solves problems, and can evolve to meet changing needs. Sometimes, a solution that's 80% as elegant but ships this week creates far more value than a perfect solution that ships next quarter.

Let me suggest a different mindset that transformed how my teams work:

1. Measure what matters. If your primary metrics are around code quality alone (test coverage, static analysis, etc.), you're incentivizing only half the equation. Balance these with metrics that capture delivery—deployment frequency, lead time for changes, change failure rate, and mean time to recovery. These four metrics (often called DORA metrics) provide a holistic view of both quality and delivery.

2. Embrace small, frequent deliveries. I noticed in your message that your team tends to work on large changes that take weeks to complete. This approach amplifies risk. Instead, encourage breaking work into smaller units deliverable within a day or two. This creates natural checkpoints, allows for faster feedback, and builds momentum that energizes the team.

Practically speaking, aim for these targets: - 0 merged PRs per day is unacceptable - 1 merged PR per day is barely acceptable - 2-4 merged PRs per day is good - 4+ merged PRs per day is exceptional

This may seem aggressive if your team is used to longer cycles, but the discipline of breaking work down this finely yields tremendous benefits in both quality and speed.

3. Implement the "30-minute rule." One of the most effective practices I've instituted is simple: if a developer is stuck on a problem for more than 30 minutes without making progress, they must seek help. This isn't about monitoring productivity—it's about removing unnecessary blockers and fostering collaboration.

I've seen too many engineers (myself included) waste days on problems that a fresh perspective could solve in minutes. Pride can be expensive. Create an environment where asking for help is seen as a strength, not a weakness.

4. Test your own work first. A culture of quality doesn't mean delegating quality assurance to others. It means each team member taking full ownership of their contributions. Before any code review, each developer should personally verify that their changes work as intended across all relevant scenarios. This habit catches issues early when they're cheapest to fix and builds a sense of craftsmanship that's about outcomes, not just code aesthetics.

5. Make commit messages meaningful. This may seem minor, but I've found it reveals much about a team's approach. Vague or mechanical commit messages ("fixed bug" or "JIRA-1234") suggest a transactional relationship with the codebase. Detailed, thoughtful messages demonstrate engagement with the work's purpose and context. They also create a valuable historical record for future developers—including your future selves.

6. Recognize that code is a means, not an end. The most profound shift in my thinking came when I realized that code exists to solve problems for people, not to satisfy developers' aesthetic sensibilities. This doesn't diminish the importance of well-crafted code; it contextualizes it. Code that's hard to maintain will eventually fail to serve users well. But code that never reaches users fails them immediately.

7. Create ceremonies that celebrate shipping, not just coding. How does your team recognize success? If recognition focuses solely on technical achievements, you may inadvertently undervalue delivery. Balance this by celebrating when features reach users and start delivering value. Make deployment a moment of pride, not just a procedural step.

8. Address the "works on my machine" mindset. This phrase reveals a fundamental misunderstanding of our purpose. We can't ship our machines—we ship solutions that work in production environments. Encourage thinking beyond local development environments to the realities of where code actually runs.

I suspect that implementing these practices will feel uncomfortable at first. They challenge deep-seated habits and possibly even identity for developers who have built their professional self-image around technical perfectionism. As a leader, your role is to help your team through this discomfort toward a more balanced perspective.

This isn't about lowering standards—it's about broadening them to include delivery as a core aspect of quality. The most beautiful code that never ships helps no one. Conversely, hastily shipped code that can't be maintained creates mounting technical debt that eventually paralyzes progress. Neither extreme serves your users or your business.

What I'm advocating is a third path: pragmatic craftsmanship. This means making intentional trade-offs with a clear understanding of their implications. Sometimes you'll choose to take on technical debt to deliver value sooner. Other times you'll invest in refactoring to enable future velocity. The key is that these decisions are made deliberately rather than by default.

Let me close with a reflection from my own journey: I used to believe that my value as a technical leader came from ensuring the highest standards in every line of code my team produced. Now I understand that my value comes from helping my team deliver meaningful solutions to real problems at a sustainable pace. The difference may seem subtle, but it has transformed how we work and, more importantly, the impact we have.

Your team's commitment to quality gives you a strong foundation. Now channel that commitment toward the ultimate measure of our success: software that makes a difference in the world.

I'm here if you want to discuss specific challenges as you navigate this balance.

With respect and confidence in your journey,

The Seasoned CTO

Last updated: Wed Apr 09, 2025, 15:09:20