Defect density: how to calculate it and what's normal
Two teams report their quarter. Team A found 60 bugs. Team B found 200. Team A looks better until you learn Team B shipped a payments rewrite and Team A shipped a settings page.
Defect density is the correction for that. It divides bugs by the size of what you built, so a big release and a small one can be compared.
Short version
- Defect density = defects divided by size. Size is usually thousands of lines of code (KLOC) or a count of features.
- The denominator decides whether the number means anything. Choose it before you calculate.
- Per KLOC works for comparing modules in the same codebase. It breaks across languages and across generated code.
- Per feature or per story point works better for product teams, but only if your sizing is consistent.
- Commonly cited ranges run from about 1 defect per KLOC for careful work up to 15 or more for typical delivered code. Treat published ranges as loose context, not targets.
- Use it to find the risky module, not to grade a team.
The formula
Defect density = number of defects / size of the thing you measured
The bug count is the easy half. The size is where every argument happens.
Two worked examples with the same 45 defects:
- The billing module has 12,400 lines of code. 45 / 12.4 KLOC = 3.6 defects per KLOC.
- The same release delivered 9 features. 45 / 9 = 5 defects per feature.
Both are correct. They answer different questions. The first tells you which part of the codebase is fragile. The second tells you how much bug work to expect from the next nine features.
Rules for the numerator
Before you count bugs, decide these and write them into your definition.
Which defects count? Usually only confirmed defects in the code you are measuring. Exclude duplicates, cannot-reproduce tickets, requirement changes filed as bugs, and issues in third-party services.
Which severities? Include all of them, but report the split. A module at 4.0 per KLOC made entirely of cosmetic issues is very different from one at 2.0 where half are critical.
Over which period? Pick one and stick to it. Common choices are the test cycle for a release, or 30 days after release for post-release density.
Found where? Density measured in testing and density measured in production tell you different things. Label which one you are reporting. Post-release density is the harsher and more honest number.
Why the denominator matters more than the formula
Here is the same module measured four ways in the same quarter, with 45 defects:
| Denominator | Size | Density |
|---|---|---|
| Total lines of code | 12,400 | 3.6 per KLOC |
| Lines changed this quarter | 2,100 | 21.4 per KLOC |
| Features shipped | 9 | 5.0 per feature |
| Story points delivered | 88 | 0.51 per point |
Four numbers, one reality. Nothing here is a lie. This is why a defect density figure without its denominator is not information.
The second row is worth attention. Density over changed lines is usually the most useful version, because bugs come from new and modified code far more than from code that has sat untouched for two years. A module with 200,000 stable lines will always look excellent on total-lines density even while its new code is a mess.
Per KLOC: when it works and when it lies
KLOC means thousands of lines of code. It is the classic denominator and it still has real uses.
Works well for:
- Comparing modules inside one codebase in one language.
- Tracking a single module over time.
- Rough capacity planning: if this module historically produces 3 defects per KLOC and you are adding 5 KLOC, expect roughly 15 bugs.
Breaks down when:
- You compare across languages. 100 lines of Python and 100 lines of Java do not do the same amount of work.
- Generated code is counted. Auto-generated API clients or migration files can double a line count without adding any risk.
- Style differs. One team's formatter puts every function argument on its own line, and their density looks 30 percent better for free.
- Someone knows they are being measured on it. Line counts are trivially inflated.
Practical guardrails: exclude generated files, tests, vendor directories, blank lines, and comment-only lines. Write the exclusion list down. Two people counting "lines of code" without a written rule will differ by 40 percent.
Per feature and per story point
Product teams usually get more out of these.
Per feature is simple to explain to non-engineers. The catch is that features are not the same size. Nine features that include a payments rewrite and a copy change are not comparable units. It works when your team already breaks work into similar-sized slices.
Per story point normalises size, but only if your pointing is stable. If your team's point scale drifted last year, your density trend measures the drift, not quality.
Per screen or per endpoint is an underused middle ground. For a web product, "defects per API endpoint shipped" or "defects per screen shipped" is concrete, hard to inflate, and easy for anyone to count.
| Denominator | Best for | Main weakness |
|---|---|---|
| Total KLOC | Comparing modules in one codebase | Old stable code hides new risk |
| Changed KLOC | Spotting where risk actually came from | Needs commit-level bug attribution |
| Feature | Explaining to stakeholders | Features vary hugely in size |
| Story point | Normalised effort comparison | Point inflation destroys the trend |
| Endpoint or screen | Web products, easy counting | Ignores internal complexity |
What is normal
Published figures vary by an order of magnitude, because everyone counts differently. The commonly cited bands, drawn from long-standing software engineering literature, look roughly like this:
| Range | Usually describes |
|---|---|
| Under 1 defect per KLOC | High-assurance work with formal review and heavy testing |
| 1 to 5 per KLOC | Well-run commercial software with real test coverage |
| 5 to 15 per KLOC | Typical delivered application code |
| Over 20 per KLOC | Rushed work, legacy areas, or a counting method that includes everything |
Two cautions. First, these figures come from very different eras and project types, so they are context, not targets. Second, your own number will move if you change your exclusion rules, so never compare your figure to a published one without knowing how the published one was counted.
The comparison that actually helps is internal. Take every module in your codebase, calculate density the same way for each, and sort the list. The top three are where your next testing hour should go. That ranking is reliable even when the absolute numbers are not.
How to use it in practice
- Write your definition once: which defects, which severities, which period, which size measure, which exclusions.
- Calculate density for each module using the same rules.
- Sort modules by density and by severity-weighted density.
- Look at the top three. Ask what they have in common — age, ownership churn, low test coverage, unclear requirements.
- Pick one and change something specific: add integration tests, split the module, add a review rule.
- Recalculate next quarter and compare to your own previous number only.
Do not set a density target for a team. Targets on this metric produce reclassified bugs and padded line counts within one quarter. Use it as a pointer to where the risk is, and let the fix be the goal.
Frequently asked questions
What is a good defect density?
There is no universal figure. Commonly cited ranges put careful commercial software around 1 to 5 defects per KLOC, but the number depends entirely on your counting rules. Compare against your own history instead.
Should I count test code in the line total?
No. Include only production code, and exclude generated files, vendor directories, blank lines, and comments. Write the exclusions down so the count is repeatable.
Is defect density better than defect count?
Yes, for comparison. Density adjusts for the size of what you shipped, so a large release does not automatically look worse than a small one.
Can I compare defect density between two teams?
Only if both use the same denominator, the same exclusions, the same severity scope, and similar technology. In most organisations, that is not true, so the comparison misleads.
How does defect density relate to defect leakage?
Density measures how many bugs a body of work contains. Leakage measures how many of them reached users. A module can be low density and high leakage, which means it has few bugs but you are not catching them.




