"What gets measured gets managed." But measuring the wrong things manages the wrong behaviors. Code health metrics can drive improvement or create dysfunction, depending on which metrics you choose and how you use them.
Effective code health measurement provides visibility into real problems, tracks meaningful progress, and guides investment. Ineffective measurement creates busywork, rewards gaming, and distracts from actual quality. This guide helps you choose metrics that actually matter.
Principles of Good Metrics
Before choosing metrics, understand what makes metrics useful.
Actionable
Good metrics drive action:
Actionable metric:
"Test coverage is 65%, below our 80% target"
Action: Increase coverage in gap areas
Non-actionable metric:
"Lines of code: 150,000"
Action: ???
Metrics should suggest what to do.
Contextualized
Good metrics have context:
Contextualized:
"Coverage is 65%, down from 70% last month"
Context: Trend, comparison, target
Not contextualized:
"Coverage is 65%"
Context: Is that good? Bad? Normal?
Numbers without context are meaningless.
Leading, Not Just Lagging
Good metrics predict problems:
Leading metric:
"Code complexity is increasing"
Predicts: Future bugs, slower development
Lagging metric:
"We had 10 bugs last month"
Describes: What already happened
Leading metrics enable prevention.
Resistant to Gaming
Good metrics are hard to manipulate:
Gameable metric:
"Lines of code removed"
Gaming: Write verbose code, then "optimize"
Harder to game:
"Mean time to recovery"
Reality: Actually measures what matters
Goodhart's Law: When a measure becomes a target, it ceases to be a good measure.
Code Quality Metrics
Metrics about the code itself.
Complexity
How complicated the code is:
@devonair complexity metrics:
- Cyclomatic complexity
- Cognitive complexity
- Average function length
- Nesting depth
High complexity correlates with bugs and slow development.
Duplication
Repeated code:
@devonair duplication metrics:
- Duplicate block count
- Duplication percentage
- Largest duplicate areas
Duplication increases maintenance burden.
Test Coverage
How much code is tested:
@devonair coverage metrics:
- Line coverage
- Branch coverage
- Coverage by component
- Coverage trend
Coverage indicates test thoroughness (with caveats).
Technical Debt
Accumulated shortcuts:
@devonair debt metrics:
- Estimated remediation time
- Debt by category
- Debt trend
- Debt age
Debt estimates guide remediation investment.
Code Smells
Patterns indicating problems:
@devonair smell metrics:
- Total smell count
- Smells by type
- Smells by component
- Smell trend
Smells suggest improvement opportunities.
Process Metrics
Metrics about how code is developed.
Lead Time
Time from commit to production:
@devonair lead time:
- Commit to merge time
- Merge to deploy time
- Total lead time
Lead time indicates delivery efficiency.
Deployment Frequency
How often you deploy:
@devonair deployment frequency:
- Deploys per day/week
- Deployment trend
Higher frequency usually indicates healthier process.
Change Failure Rate
How often changes cause problems:
@devonair change failure rate:
- Deployments causing incidents
- Rollback frequency
Lower failure rate indicates better quality.
Mean Time to Recovery
How fast you recover from failures:
@devonair MTTR:
- Detection to recovery time
- By severity
- Trend
Fast recovery reduces impact of failures.
Maintenance-Specific Metrics
Metrics about maintenance activities.
Dependency Currency
How up-to-date dependencies are:
@devonair dependency currency:
- Dependencies out of date
- Average age behind latest
- Security vulnerabilities
Currency indicates maintenance attention.
Issue Backlog
Outstanding issues:
@devonair issue backlog:
- Total open issues
- By severity
- By age
- Trend
Backlog size indicates whether you're keeping up.
Issue Velocity
How fast issues are resolved:
@devonair issue velocity:
- Issues resolved per week
- Mean time to resolution
- By issue type
Velocity indicates maintenance effectiveness.
Maintenance Time Allocation
Time spent on maintenance:
@devonair time allocation:
- Percentage on maintenance
- Percentage on features
- Trend
Allocation shows maintenance investment.
What NOT to Measure
Some metrics cause more harm than good.
Lines of Code
Avoid: Lines of code written
Why: More code isn't better
Gaming: Write verbose code
Better: Functionality delivered
Commits Per Developer
Avoid: Individual commit counts
Why: Encourages small, meaningless commits
Gaming: Split work into tiny commits
Better: Team delivery outcomes
Bugs Per Developer
Avoid: Bug attribution to individuals
Why: Creates blame culture, discourages reporting
Gaming: Don't find bugs, don't report bugs
Better: System-level bug trends
100% Coverage
Avoid: Requiring exactly 100% coverage
Why: Encourages testing trivia, not value
Gaming: Write tests for getters/setters
Better: Coverage of critical paths
Building Dashboards
How to present metrics effectively.
Single View of Health
Overview dashboard:
@devonair health dashboard:
- Overall health score
- Key metrics at a glance
- Trend indicators
- Attention areas
Quick visibility into overall status.
Trend Displays
Show direction over time:
@devonair trend visualization:
- Metrics over time
- Comparison to targets
- Progress indication
Trends matter more than snapshots.
Drill-Down Capability
Detail when needed:
@devonair drill-down:
- Repository-level metrics
- Component-level metrics
- Issue-level detail
Enable investigation of problems.
Alert Integration
Proactive notification:
@devonair metric alerts:
- Alert when metrics degrade
- Alert when thresholds crossed
- Alert on trends
Don't wait for dashboard check.
Using Metrics Effectively
Metrics only help if used well.
Regular Review
Schedule metric review:
@devonair review cadence:
- Daily: Critical alerts only
- Weekly: Key metric trends
- Monthly: Comprehensive review
- Quarterly: Strategic assessment
Consistent review drives action.
Target Setting
Set meaningful targets:
@devonair target approach:
- Based on current state
- Achievable but stretching
- Adjusted over time
- Team-agreed
Targets provide direction.
Action from Data
Convert metrics to action:
@devonair action process:
- Metric shows problem
- Investigate root cause
- Plan improvement
- Execute and verify
Metrics without action are pointless.
Avoid Metric Fixation
Remember metrics aren't the goal:
Keep perspective:
- Metrics indicate health
- Health isn't the metric
- User value is the goal
- Metrics serve decisions
Metrics serve outcomes, not vice versa.
Getting Started
Build your measurement system.
Choose key metrics:
@devonair select metrics:
- 3-5 quality metrics
- 2-3 process metrics
- 2-3 maintenance metrics
Start small, expand as needed.
Establish baselines:
@devonair baseline:
- Current state for each metric
- Document starting point
- Enable progress tracking
Baselines enable comparison.
Set initial targets:
@devonair set targets:
- Modest improvement goals
- Achievable in 3-6 months
- Adjust as you learn
Targets guide effort.
Build visibility:
@devonair build visibility:
- Dashboard for key metrics
- Alerts for critical thresholds
- Regular review schedule
Visibility enables management.
Measuring code health effectively requires choosing the right metrics, presenting them usefully, and acting on what they reveal. Start with a few key metrics, build good dashboards, and establish a habit of regular review and action. Measurement should drive improvement, not just report numbers.
FAQ
How many metrics should we track?
Start with 5-10 key metrics. More than that becomes overwhelming. You can track more in the background, but focus attention on a small set of meaningful metrics.
What's a good test coverage target?
80% is a common target for most code. 100% is rarely worth the effort. Focus coverage on critical paths and business logic. Some code (generated, trivial) doesn't need high coverage.
How do we avoid metrics becoming punitive?
Focus on system metrics, not individual metrics. Use metrics for improvement, not blame. Celebrate progress rather than punishing shortfalls. Make metrics team goals, not individual targets.
Should metrics be public?
Team-level metrics can be healthy to share. Individual metrics generally shouldn't be public. Transparency builds accountability, but surveillance creates dysfunction.