Engineering Practitioner Brief, 18 July 2026
Refactoring Cost Per Line of Code
People ask for a dollars-per-line number because it is the one input that looks countable: run a line count, multiply, done. This page gives that number, honestly, by deriving it from a reproducible per-module sizing model rather than inventing a rate. It also explains why the figure is a sanity check and not an estimate, and where the widely-quoted SonarQube 30-minutes-per-line figure actually belongs.
Refactoring cost per line of code, at a glance
- $4 to $8 per line — well-tested module (80%+ coverage)
- $7 to $16 per line — partially tested (30 to 50% coverage)
- $14 to $27 per line — untested legacy (under 20% coverage)
Model, not a quote: engineer-hours from the sizing table below, times an $80 to $90 US fully-loaded hourly rate, divided by effective lines of code, for a representative 3,000-line module. Reproduce it with your own rate and line count.
How the per-line number is derived
There is no published, authoritative price to refactor a line of code, because no two lines cost the same to change. So rather than assert a rate, this page derives one from the same engineer-hours model used on the legacy code refactoring cost page. The formula is deliberately plain:
cost per line = (engineer-hours × loaded hourly rate) ÷ effective lines of codeEffective lines of code means the lines a human actually reads and reasons about: generated code, vendored dependencies, and comments are excluded. The loaded hourly rate of $80 to $90 comes from a US fully-loaded senior cost of $160,000 to $200,000 per year (salary plus benefits, equity, taxes, and equipment) spread across productive hours. The engineer-hours come from the sizing table below, which is the load-bearing input.
Cost per line by test coverage
The single biggest driver of per-line cost is whether the code has tests. An untested module forces a characterization-test backfill before any safe change, and that backfill routinely consumes 30 to 60 percent of total effort, the pattern Michael Feathers described in Working Effectively with Legacy Code. The table below works a representative 3,000-line module through the formula above.
| Test coverage | Engineer-hours (3,000 LOC) | Dollar cost at $80 to $90/hr | Cost per effective line |
|---|---|---|---|
| Well-tested (80%+) | 140 to 280 | $11,200 to $25,200 | $4 to $8 |
| Partially tested (30 to 50%) | 280 to 520 | $22,400 to $46,800 | $7 to $16 |
| Untested (under 20%) | 520 to 900 | $41,600 to $81,000 | $14 to $27 |
Hours are the 1,500-to-4,000-LOC band from the legacy refactoring sizing table, applied to a 3,000-line module. Divide the dollar column by 3,000 to get the per-line figure. Larger, cleaner modules land below this range (down toward $4); small, entangled ones climb above it.
Where the SonarQube 30-minutes-per-line figure fits
The number most people find when they search for cost per line is SonarQube's default of 30 minutes per line. It is real, but it does not mean what it is usually quoted to mean. SonarQube uses it as the cost to develop one line of new code, and it exists only as the denominator of the technical debt ratio: remediation cost divided by (cost per line times number of lines). The default is configurable through the sonar.technicalDebt.developmentCost setting.
Development cost (SonarQube default): 30 minutes per line, i.e. roughly $40 to $45 to author a new line at $80 to $90 per hour. This measures greenfield writing, not refactoring.
Refactoring cost (this model): $4 to $27 per existing line across a module, because most lines are read and kept rather than rewritten. The cost per line you actually change can exceed the greenfield rate, since you pay to reconstruct intent and pin behaviour before touching anything.
Source for the 30-minute default: SonarQube Server documentation, “Understanding measures and metrics” and the technical-debt parameters reference (docs.sonarsource.com, checked July 2026). See SonarQube technical debt ratio and the SQALE method for the full calculation.
Why per-line is a sanity check, not an estimate
A per-line rate hides the four things that actually move a refactor bill. Two modules of identical size can differ threefold in cost, so a line count alone will mislead anyone funding the work.
- Test coverage. The gap between the well-tested and untested rows above is roughly 3x, and it comes entirely from characterization-test backfill, not from the code being longer.
- Blast radius. A function called from three places is a different job from one called from three hundred. Each caller, message consumer, or downstream reader adds coordination overhead the line count cannot see.
- Deployment risk. A library refactor behind a semver bump is cheap. A zero-downtime schema migration on a live table is not, and the difference is hundreds of hours of migration tooling and rehearsal. See database schema debt cost.
- Domain knowledge. If the original author is on the team, cost drops perhaps 20 percent. If the only reference is a stale design doc, the same code takes 50 percent longer while intent is reconstructed.
Use the per-line number the way you would use a price-per-square-foot for a house: fine for a first gut check and for comparing two quotes, useless as the actual estimate. When the number needs to survive a budget conversation, size the specific module with the full engineer-hours model instead.
Worked example
A team wants to refactor a 6,000-line untested billing module. A per-line gut check using the untested rate of $14 to $27 gives a range of about $84,000 to $162,000. Sizing it properly, the 4,000-to-8,000-LOC untested band is 1,000 to 1,800 engineer-hours, which at $80 to $90 per hour is $80,000 to $162,000 in direct engineer time before any deployment-risk premium. The two land in the same place, which is the point: the per-line figure is a fast way to check that a detailed estimate is not off by an order of magnitude, and to catch a quote that has quietly priced the same module at $500,000 or at $15,000.
Size the specific module
The per-line rate is the gut check. The engineer-hours model is the estimate you can defend in a budget review.