Every product that has ever shipped has known bugs sitting in its backlog on launch day — that part isn't a failure. The real skill is deciding, explicitly and out loud, which ones get fixed before release, which ship as a documented fast-follow, and which the team agrees to live with. "Fix all the bugs" isn't a strategy; it's an abdication of that decision.
Quick answer: Triage every bug on two axes — severity (how bad is it when it hits) and frequency (how often does it hit) — then apply a fixed rule for what counts as a release blocker. Everything else is a fast-follow or a deliberate won't-fix, decided on purpose and written down.
Why "Fix All the Bugs" Isn't a Strategy
"Fix all the bugs" sounds responsible, but it's actually a refusal to prioritize — it treats a null-pointer exception in an admin-only export tool the same as a checkout flow that silently drops orders. Every hour spent on the first is an hour not spent on the second, or on a feature customers are waiting for.
Engineering time is a fixed pool, and bugs compete inside it with everything else on the roadmap. Stripe's 2018 "Developer Coefficient" survey of engineering leaders found that developers report spending roughly two-fifths of a typical week on maintenance and technical debt rather than new work — a number that tracks with what most PMs see once they actually audit sprint capacity. That's not a scandal; it's the baseline cost of running software in production.
The job of a PM isn't to drive that number to zero. It's to make sure the bugs consuming that time are the ones that actually matter, and that everyone — engineering, support, leadership — agrees on why. Three things make that possible:
- A shared severity language, so "bad bug" means the same thing to a PM, an engineer, and a support lead.
- A frequency estimate, so rare edge cases don't get the same urgency as bugs hitting every user.
- A written rule for what blocks a release, decided before the pressure of a ship date, not during it.
Without those three, triage becomes whoever argues loudest in the bug review — usually the engineer most recently paged, or the stakeholder most recently burned. That's not prioritization; it's recency bias with a Jira ticket attached.
Triage itself is delivery-track work, but the severity judgment behind it usually leans on discovery signals already in motion — a support pattern, a usability session, a churn interview. Keeping that discovery input flowing into delivery decisions, rather than triaging in a vacuum, is the same discipline covered in balancing discovery and delivery in dual-track agile.
The Severity × Frequency Triage Matrix
Every bug gets scored on two independent axes — severity (how bad is the outcome when it happens) and frequency (how often it happens) — and the combination, not either axis alone, determines the response. A rare catastrophic bug and a constant minor annoyance can land in the same triage tier for very different reasons.
This distinction isn't a PM invention. The ISTQB (International Software Testing Qualifications Board) glossary has long separated severity (the impact of the defect on the system) from priority (the urgency of fixing it), precisely because conflating them produces bad calls. A severe bug that almost never fires and a minor bug that fires constantly both need attention — just not the same attention.
Google's public Android and Chromium issue trackers formalize the same split, tracking priority and severity as independent fields (commonly seen as P0–P4 alongside S0–S4 on public bug listings). That separation lets a triage team reason about impact and urgency on their own terms, before combining them into one call.
Here's a working matrix you can adapt to your own product:
| Severity ↓ / Frequency → | Rare (under ~5% of sessions) | Common (roughly 5–30%) | Pervasive (30%+ or a core flow) |
|---|---|---|---|
| Critical — data loss, security exposure, broken payment/auth | Hotfix immediately, outside the normal cycle | Release blocker | Release blocker, stop-ship |
| High — core feature broken, no workaround | Fast-follow this sprint | Release blocker | Release blocker |
| Medium — real friction, workaround exists | Backlog, prioritize normally | Fast-follow next sprint | Fast-follow this release |
| Low — cosmetic, edge case, no functional loss | Backlog, may never get fixed | Batch with related work | Fast-follow if it's visible to a segment that matters |
Read the matrix as a starting rule, not gospel. A Medium/Pervasive bug in a workflow that drives revenue can outrank a High/Rare bug nobody will ever hit — severity and frequency are inputs to judgment, not a lookup table that replaces it. What the matrix buys you is a shared vocabulary: when someone says "this is a High/Common," the whole team knows roughly what that means before the debate starts.
Where Frequency Estimates Actually Come From
Frequency isn't a guess — it's usually available in the systems you already have. Pull it from:
- Error-tracking tools (Sentry, Bugsnag, Datadog) for exception rates against total sessions.
- Support ticket volume tagged to the same root cause, weighted by how many tickets typically represent one silent sufferer.
- Analytics funnels showing drop-off at the exact step the bug affects.
- Direct testing for bugs too new or rare to have telemetry yet — an engineer's best estimate, labeled as such.
A severity score without a frequency estimate is an opinion. Pairing them is what turns triage into a defensible decision rather than a vibe.
What Makes a Bug a Release Blocker vs. a Fast-Follow
A bug is a release blocker only if it meets one of four conditions: it causes data loss or corruption, it blocks a core revenue or activation path with no workaround, it creates security, privacy, or compliance exposure, or it breaks a commitment the company has already made publicly (an SLA, a contract, a regulatory deadline). Everything else is a fast-follow candidate.
This rule matters because "release blocker" gets used loosely under deadline pressure — usually by whoever is most anxious about the specific bug in front of them. Writing the four conditions down, before a release is on the calendar, takes the decision out of that moment and makes it checkable instead of political.
Microsoft's engineering teams have long used a related device called the bug bar — a documented, pre-agreed threshold that a build must clear before it ships, originally formalized as part of the Security Development Lifecycle and applied broadly across Windows and Office releases. The point of a bug bar isn't to list every acceptable bug; it's to state the criteria in advance so nobody has to negotiate them under deadline stress.
A fast-follow, by contrast, is a bug the team has explicitly decided to ship with, paired with:
- A committed timeline — "within two weeks," not "soon."
- A visible tracking ticket, linked from release notes if the bug is customer-facing.
- A mitigation — a workaround, a support macro, or a known-issues note — so the gap between "known" and "fixed" isn't silent.
A bug that's merely annoying is a fast-follow. A bug that's irreversible — data loss, a security hole, a broken promise — is a blocker. Reversibility is doing more work in that sentence than severity alone.
The same logic that governs a release-blocker rule should govern how a team runs its broader delivery cadence — see the complete guide to agile delivery for how sprint commitments and definition-of-done criteria connect to this same discipline.
One Backlog, Two Demands: How Bug Work Competes With Features
Bugs and features should live in one prioritized backlog, not two competing lists, because they're both claims on the same finite engineering capacity. Splitting them into separate backlogs just hides the trade-off instead of making it.
Two common allocation models handle this in practice:
- A fixed capacity split — commonly 15–20% of a sprint reserved for bug work, regardless of what's queued, so maintenance never fully starves. This is simple and predictable, but it can either overfund a quiet period or underfund a bad one.
- A unified scoring model — every backlog item, bug or feature, gets scored on the same framework (cost of delay against effort) and ranked in one list.
WSJF(Weighted Shortest Job First), popularized by the Scaled Agile Framework, is the most common version of this: a P1 bug with high user impact can out-rank a nice-to-have feature, and a cosmetic bug can rank below almost everything.
| Approach | Strength | Weakness |
|---|---|---|
| Fixed capacity split | Predictable, protects against total bug neglect | Can misallocate — too much slack in quiet weeks, too little after a bad release |
Unified scoring (e.g. WSJF) | Reflects real relative value, no artificial wall | Requires discipline to score honestly; easy to under-score bugs that are "just annoying" |
| Ad hoc / squeaky wheel | None | Rewards whoever escalates loudest, not what matters most |
Whichever model a team uses, the decision belongs somewhere specific — usually the PM, in partnership with engineering leadership, and it's worth being explicit about that ownership. The boundary between what a product manager decides and what a product owner executes tactically is exactly the kind of ambiguity that erodes trust in the process; see PM vs. PO role boundaries for how to draw that line before a bug triage meeting turns into a turf dispute.
Severity, in particular, should be assessed against the job the customer was actually trying to get done in that moment, not just against the technical failure mode. A bug that blocks someone mid-checkout is worse than the same error code appearing in a settings page nobody visits weekly — the Jobs to Be Done framework is a useful lens for weighting severity by what the user was actually trying to accomplish when the bug hit them, not just by stack trace.
Where that moment sits in the relationship matters too. The same bug lands harder during a first-time onboarding step than it does for a three-year power user who already trusts the product enough to shrug it off — mapping bugs against a customer journey is often the fastest way to calibrate severity beyond the raw technical failure mode.
Bug Bankruptcy: The Trust Cost of Giving Up on the List
A backlog with thousands of open, untriaged bugs isn't cautious — it's a trust liability, because nobody believes any item on it will ever be looked at, including the real ones worth fixing. At some point, a team has to choose between actually triaging that backlog or formally declaring it dead.
Bug bankruptcy — closing out a large stale backlog en masse rather than letting it decay indefinitely — is a practice that engineering teams at companies like Trello and Basecamp have written about publicly, as a response to bug lists so large that keeping them "open" had stopped meaning anything. The logic: an untriaged backlog of 4,000 bugs doesn't represent 4,000 commitments. It represents zero, because nobody can act on a list that size, and everyone quietly knows it.
The trust cost runs in two directions:
- Internally, engineers stop trusting the backlog as a source of truth. If "P2" hasn't moved in eighteen months, the label stops meaning anything, and estimation, planning, and even new triage calls degrade along with it.
- Externally, customers who filed a bug and got silence learn not to report the next one — which is worse than never having the feedback channel at all, because it looks healthy while quietly going blind.
Declaring bankruptcy isn't giving up; it's admitting out loud what was already true. The alternative — an infinite backlog nobody touches — pretends every bug is still "in consideration," which is a much bigger dishonesty than closing 3,000 tickets with a note explaining why.
The failure mode isn't shipping with known bugs. It's letting the list of known bugs grow so large and untended that "known" stops meaning "decided about."
This is also where a bug's ripple effects across the wider system matter, not just its immediate symptom. A rare-looking crash in one module can be the visible edge of a deeper coupling problem that will keep resurfacing in new forms until the underlying cause is addressed — the kind of second-order effect that systems thinking is built to catch before a triage team keeps re-triaging the same root cause under five different bug numbers.
A Worked Triage: Three Bugs, Three Different Calls
The matrix and the blocker rule only prove their worth against real bugs, so here's a worked triage of three realistic issues for a SaaS product a week before a release — same product, three different verdicts, each with a documented reason.
| Bug | Severity | Frequency | Verdict | Reasoning |
|---|---|---|---|---|
| A. Analytics event fails to fire on one legacy Android browser after checkout | Low — no user-facing impact, only missing telemetry | Rare — affects a browser under 1% of sessions | Ship broken; backlog, no committed date | No customer harm, tiny reach, and fixing it competes with real work. This is exactly the kind of bug a "fix everything" policy would waste a sprint on. |
| B. CSV export silently drops the last row for exports over 10,000 rows | Medium — data completeness issue, but a re-export or manual check works around it | Common — hits roughly 8% of exports, concentrated among power users | Fast-follow within two weeks; ship with a known-issue note | Real friction for a specific, valuable segment, but recoverable and not urgent enough to hold the release. The commitment and the note are what keep this from becoming silent debt. |
| C. Password reset link returns an expired-token error for ~20% of requests during peak signup hours | Critical — locks users out of their own accounts, no workaround, adjacent to security/support load | Pervasive during exactly the windows new-user growth depends on | Release blocker; hold the release until fixed | Irreversible in the moment (a locked-out user churns instead of retrying), touches the activation path directly, and creates a support and trust cost that outweighs any date slipped to fix it. |
Notice what makes each call defensible: it isn't "this bug feels bad" or "this bug feels fine" — it's severity and frequency, checked against the four blocker conditions, with the reasoning written down where the next person doesn't have to re-litigate it. Bug A ships broken on purpose. Bug B ships with an honest asterisk. Bug C doesn't ship at all until it's fixed.
That written reasoning matters as much as the verdict. A stakeholder who disagrees with "we're shipping Bug B" can argue with a documented severity/frequency call — they can't productively argue with silence, and silence is what most bug triage looks like without a system behind it.
Turning the Triage Call Into a Documented Gate
The hardest part of bug triage usually isn't the analysis — it's that the decision gets made verbally, in a standup or a Slack thread, and then nobody can find it three weeks later when someone asks why a known bug shipped. The fix is treating "what quality bar must this clear to ship" as a written, agreed-on gate, not a recurring debate.
This is precisely the gap Prodinja's Spec Studio is designed to close. Because a spec in Spec Studio behaves like a living PRD with PR-style diffs and readiness gates, a PM can write the release-blocker criteria — data loss, no security exposure, no broken activation path, whatever the team agrees — directly into the spec's readiness checklist. A spec can't move to "ready to ship" until that gate is explicitly marked clear.
The triage call that used to live in a Slack thread instead lives in the document everyone already checks before hand-off, with the same audit trail as any other spec change.
The quality bar doesn't have to be identical on every release — it just has to be written down before the deadline, not negotiated during it.
That doesn't replace the judgment call about severity and frequency — a PM and engineering lead still have to make that call. What it changes is where the decision lives afterward: as a documented, revisitable gate the team agreed to, instead of a hallway argument nobody can point back to when the next release raises the same question.
Key Takeaways
- "Fix all the bugs" isn't a strategy — it treats every defect as equally urgent and quietly starves whichever feature or fix actually deserved the time.
- Score every bug on two independent axes, severity and frequency, using the same
ISTQB-style distinction between impact and urgency that keeps triage from collapsing into a single "bad/not bad" judgment. - Define release-blocker criteria before a ship date is on the calendar: data loss, a blocked core path with no workaround, security/compliance exposure, or a broken public commitment — everything else is a fast-follow.
- Put bugs and features in one prioritized backlog, scored on the same terms (a fixed capacity split or a unified model like
WSJF), so the trade-off is visible instead of hidden behind two separate lists. - An untriaged backlog isn't caution — it's a trust cost. Bug bankruptcy, formally closing a stale list rather than letting it silently rot, is often more honest than pretending every open ticket is still "in consideration."
- Write the reasoning down, not just the verdict. A documented severity/frequency call with a rule behind it survives scrutiny; a verbal one gets relitigated every release.
Frequently Asked Questions
How many bugs should a product ship with?
There's no universal number — the right measure isn't bug count, it's whether every open bug has been triaged and has an owner for the decision. A product with 200 triaged, deliberately-deferred low-severity bugs is healthier than one with 20 bugs nobody has looked at.
What's the difference between a release blocker and a P1 bug?
A P1 label typically signals high urgency within normal prioritization, while a release blocker is a narrower, stricter category — a bug that meets one of a small set of pre-agreed conditions (data loss, a blocked core path, security exposure, or a broken public commitment) that halts the release entirely. Most P1 bugs are fast-follows, not blockers.
Should the PM or the engineering lead decide which bugs get fixed?
It should be a joint call with clear ownership: engineering usually estimates severity and technical risk, while the PM weighs that against user and business impact and makes the final ship/hold decision, ideally against a written blocker rule rather than case-by-case negotiation. This is a smaller version of the broader question of who decides strategy versus who executes it.
What is bug bankruptcy and is it actually a good idea?
Bug bankruptcy means formally closing a large backlog of stale, untriaged bugs instead of leaving them open indefinitely, and it's a good idea when the backlog has grown so large that "open" has stopped meaning anything. It's honest housekeeping, not negligence, as long as genuinely important bugs are re-triaged and re-opened deliberately, not lost in the sweep.
How much sprint capacity should go to bug fixes versus new features?
A commonly used starting point is reserving roughly 15–20% of sprint capacity for bug work as a floor, then letting a unified prioritization model like WSJF decide anything above that floor alongside features. The right number varies by product maturity — a newly launched product typically needs a higher share than a mature one with a stable codebase.