Writing
Speed vs. Quality: Why Is It So Hard to Get the Balance Right?
Speed to market matters. So does engineering quality. The hard part is knowing which one a given piece of work needs more, and making that tradeoff without making the next release harder.
By Ka Lun Chan · Engineering leadership · Leadership / Delivery / Engineering judgment
Why speed and quality feel like opposites
For more than 20 years I’ve watched teams have the same argument. The business wants the feature this month. Product wants to answer a customer who is waiting. Engineers want something reliable that they can still change next year. Each of them is right about something, and the meeting still turns into speed against quality.
Speed and quality are hard to balance because business and engineering see different risks, and because the right level of quality changes from one piece of work to the next. The two are connected: small, well-tested changes are usually the fastest way to ship, and a codebase full of unmanaged shortcuts slows down every release after it.
Why speed to market matters
I believe speed matters. A great product that arrives too late may not matter at all. Customers don’t wait, competitors keep shipping, and market conditions change while a team is still designing.
I’ve worked in startups and in larger organizations. The pressure to deliver feels different in each, but the business reality is the same: software creates value only once someone can use it. A carefully architected system that took six months, for customers who needed it three months ago, hasn’t accomplished much.
Speed to market matters because early, working releases bring revenue and feedback sooner. Feedback from real customers tells a team whether it is solving the right problem, which another architecture meeting or another sprint can’t tell it.
There is a catch. Shipping quickly only helps when what you ship works.
Quality is not the same as perfect code
When engineers talk about quality, they usually mean the code: clean architecture, design patterns, test coverage, documentation, reusable components. Those things matter. Pursued for their own sake, they also become a cost.
I’ve seen engineers spend days debating an abstraction for code that would only ever run in one place. I’ve also seen teams adopt microservices before they had the traffic or the team size to justify them, a question I wrote about in should it be a microservice? That is extra engineering, and it doesn’t make the product better.
In software engineering, quality means a system that is reliable enough for its purpose, maintainable enough for its expected lifetime, and safe enough for its potential impact. The engineering investment should match the risk and the business need.
A simple internal reporting tool doesn’t need the investment of a financial transaction system. A prototype doesn’t need the production readiness of a platform serving hundreds of thousands of users. Making that judgment correctly is the hard part.
Why the balance is so hard to get right
Business and engineering see different risks
Business leaders see the cost of moving too slowly: customers lost, revenue missed, a competitor shipping first, a commitment that slips. Engineers see the cost of moving too fast: production incidents, security vulnerabilities, fragile architecture and work that comes back later.
Neither side is wrong. A missed market opportunity is expensive, and so is an outage. An engineering leader’s job is to weigh both against the actual business impact. Arguing that engineering needs more time is a much smaller job, and usually a less useful one.
Activity gets mistaken for progress
I’ve seen teams work extremely hard and still move slowly. Tickets move, pull requests open, the calendar is full of meetings, and very little reaches production. Sometimes the team is building things nobody needs. Sometimes it is building too many things at once.
Before asking engineers to move faster, ask whether they are building the right things. Removing work that never needed to happen speeds up delivery and costs nothing in quality.
Technical debt is easy to create and hard to measure
Under pressure, shortcuts look cheap. Skip a test. Duplicate some logic. Add one more condition in the frontend. Push the refactor to next sprint. Sometimes those are reasonable calls.
The trouble starts when a temporary shortcut becomes permanent architecture. Another feature comes to depend on the workaround, then another, until a change that should take two days takes two weeks because nobody wants to touch that code.
Technical debt is acceptable when it is a deliberate decision: you know what you are borrowing, why, and how you will pay it back. Unmanaged debt is the problem, and it rarely goes away unless someone schedules the time to address it.
Not every change carries the same risk
Compare two changes. One updates the copy on a marketing page. If something goes wrong, you fix it quickly and the business impact is small. The other changes the ownership validation rules in an application for a federal small business certification program. A mistake there could block eligible applicants, let incorrect information through, or disrupt a process people depend on. I’ve built government applications where rules like that are the core of the product.
I would not give those two changes the same testing and review. Many organizations do anyway. That delays the low-risk work and can still leave the high-risk work under-protected.
Engineering process should be risk-based. Two questions sort most changes: what would a failure cost, and how easily could you undo it?
Ship behind a safeguard
Feature flag, monitoring and a tested rollback. Release to a few users first.
Example A new step in a customer workflow
Slow down
Tests on the rules themselves, a second reviewer, a staged rollout and a recovery plan.
Example Ownership validation in a certification application
Ship and fix forward
Light review and a quick release. If it’s wrong, fix it.
Example Copy on a marketing page
Decide before you ship
The code is small and the commitment is large. Review the design as well as the diff.
Example A field name in a public API
Smaller releases are faster and safer
It can sound contradictory, but shipping more often usually produces better software, as long as each release is small. Picture the same quarter of work released two ways.
| One big release every three months | Small releases through the week | |
|---|---|---|
| Size of each release | Dozens of features at once | One small change |
| Code review | Large pull requests, skimmed | Small pull requests, read |
| Integration and testing | Weeks, at the end | Continuous, as you go |
| When something breaks | Hard to tell which change caused it | Usually the last change |
| Rollback | All or nothing | Undo one change |
| Customer feedback | Months after the work started | Days after |
In most situations the second approach wins on speed and on safety. That is why I’ve become a strong believer in smaller user stories and smaller pull requests, and in deploying often.
Shipping in smaller increments improves quality because each change is easier to review, test, trace and roll back. What a team should shorten is the time between making a change and delivering it safely to users. How fast the code gets typed matters much less.
How I balance speed and quality
I don’t think there is a universal formula. These are the five principles I try to follow.
1. Start with the business impact
Before deciding how much engineering effort a piece of work deserves, find out why it matters:
- What happens if we deliver two weeks late?
- What happens if the feature fails, and how many customers are affected?
- Can we reverse the change easily?
- Is this an experiment or a critical business workflow?
The answers show where speed matters most and where quality needs extra investment.
2. Define the minimum acceptable quality
Moving fast shouldn’t mean abandoning engineering standards. For production software I keep a floor: no known critical security vulnerabilities introduced by the change, tests appropriate to the risk, basic error handling, monitoring or another practical way to detect failures, and a reasonable rollback or recovery plan. The depth of testing and safeguards grows with the potential impact.
You can reduce scope, simplify the implementation and postpone nonessential improvements. You shouldn’t knowingly ship an unacceptable risk to meet a deadline.
3. Reduce scope before you reduce quality
This is one of the most useful lessons I’ve learned. When a deadline gets close, the first conversation should be about scope. Testing comes up only after that. Do we need all ten features? Can we release three now and seven later? Can we simplify the workflow and deliver the most valuable part first?
- 01Cut scopeShip three of the ten features now and seven later.
- 02SimplifyA simpler workflow that still solves the core problem.
- 03Postpone the nonessentialPolish and nice-to-haves move to a follow-up with an owner.
- 04Make the tradeoff visibleWrite down what was deferred and what it costs, then recommend.
The quality floor for production software
- No known critical security vulnerabilities introduced
- Tests matched to the risk
- Basic error handling
- A practical way to detect failures
- A rollback or recovery plan
A smaller, reliable release is often better than a larger, unstable one, and the business still gets value sooner.
4. Make technical tradeoffs visible
Sometimes we really do need a shortcut. That is part of engineering, and the decision should be deliberate. If we postpone a refactor to meet a deadline, it gets documented. If we accept a workaround, we write down its limits. If a feature needs more testing after release, the follow-up work is created and someone owns it.
Leadership needs to understand the tradeoff too, in business terms. “We need more time because of technical debt” doesn’t give them anything to decide. This does:
“We can deliver this feature this week using the existing implementation. Future changes to this workflow will stay difficult, and we expect more regression risk. I recommend scheduling the refactor before we expand the feature further.”
Then make sure the follow-up actually gets prioritized. A ticket that sits in the backlog forever isn’t a plan.
5. Invest in what makes the next release faster
Organizations often treat any engineering work that doesn’t produce a feature as overhead: automated testing, CI/CD pipelines, monitoring, development environments, fewer unnecessary dependencies, better code review. None of it earns revenue this week. All of it lowers the cost and risk of every release after.
Early in my career I scripted the routine work on a carrier network in Expect and Korn shell, before anyone called it DevOps. A large part of my work since has been deployment processes, infrastructure and engineering workflows. The aim was never more tools. It was making it easier for engineers to ship a change with confidence.
Good engineering practices should make a team faster over time. If a process keeps blocking delivery without meaningfully reducing risk, it is worth asking whether it still serves its purpose.
What AI changes about speed and quality
AI-assisted development makes this more interesting. I can now build things in a few hours that used to take me days or even weeks. That is exciting, and it comes with a new risk.
AI has made code much cheaper to generate. It hasn’t made code cheaper to understand, validate or maintain, so engineering judgment matters more with AI in the loop, and teams can now create technical debt faster than ever.
You can generate an entire feature quickly. Someone still has to ask whether it handles the edge cases, follows your security model, avoids unnecessary complexity, solves the actual business problem, and will make sense to whoever reads it six months from now.
If a team measures productivity by how much code it produces, AI will make those numbers look fantastic, and they may say little about value delivered. I wrote about that gap in the hidden cost of AI coding. The better use is shorter feedback loops: faster tests, quicker exploration of options, less repetitive work.
Bring leadership options, not just a request for more time
Working with executives taught me that they rarely want to hear only about problems. They need options. So instead of “We can’t deliver this because we need more testing,” I’d bring a recommendation:
“We can release the core workflow this week with the existing safeguards. The remaining functionality adds validation scenarios, so I recommend moving it to the next release. That delivers business value now without increasing risk to the critical workflow.”
Leadership isn’t being asked to choose between speed and quality without context. They get a practical way to have both where that’s possible, and when the tradeoff is real, its consequences are on the table. That is how I think about running engineering in general.
Short answers
How do you balance speed and quality in software engineering?
Start with the business impact of the work, keep a minimum quality bar for anything in production, and match testing and review to the risk of each change. When a deadline is at risk, cut or simplify scope before cutting quality, and make any shortcut a documented decision with an owner for the follow-up.
Is speed to market more important than quality?
Neither wins every time. Speed matters because software creates value only once customers can use it, and early releases bring feedback. Quality matters because shipping fast only helps when the release works. The right balance depends on what a failure would cost and how easily the change can be undone.
When is technical debt acceptable?
Technical debt is acceptable when it is a deliberate choice: the team knows what it is borrowing, why, and how it will pay it back, and leadership understands the tradeoff. It becomes a problem when temporary shortcuts turn into permanent architecture and nobody schedules the time to fix them.
Do smaller releases improve software quality?
Usually, yes. Small releases mean smaller pull requests that get read properly, problems that are easier to trace to one change, simpler rollback, and earlier customer feedback. In most situations they are both faster and safer than one large release every few months.
Does AI make the speed vs. quality tradeoff harder?
It raises the stakes. AI has made code much cheaper to generate, but not cheaper to understand, validate or maintain, so teams can create technical debt faster than before. AI helps most when it shortens feedback loops, improves testing and removes repetitive work, and engineering judgment still decides what ships.
The goal is sustainable speed
I’ve seen teams move incredibly fast for a few weeks and spend months fixing what they shipped. I’ve also seen teams design for so long that the opportunity passed. Sustainable speed means delivering business value quickly without making the next delivery harder. Sometimes that means shipping something imperfect. Sometimes it means slowing down for a critical risk, saying no to complexity, or challenging a deadline because a failure would cost too much. After more than two decades, I don’t think that call ever gets easy. Experience helps you see which tradeoffs are worth making.
Speed gets a product to market, and quality keeps it there. Sustainable engineering lets a team do both, release after release.