Skip to main content
the readable codebase

Measuring Progress: The Readability Dashboard

4 min read Chapter 27 of 27

Measuring Progress: The Readability Dashboard

The Smell

The logistics platform team has been making incremental readability improvements for two months. The tech lead feels the codebase is better. The team agrees. The product manager asks: “How much better? Can you show me a number?” The tech lead cannot. The improvements are felt but not measured. The next time the product manager allocates time between features and tech debt, the improvements have no evidence to support continuing.

Unmeasured improvement is invisible improvement. It competes for time against features that have clear metrics: revenue impact, user growth, engagement numbers. Without its own numbers, readability improvement loses every prioritization debate.

The Cognitive Cost

When readability improvement is unmeasured, the team cannot answer basic questions: Are we getting better or worse? Which areas improved the most? Where should we focus next? Each of these questions requires intuition instead of data. The team’s intuition may be correct, but intuition does not survive a prioritization meeting.

When readability improvement is measured, progress is visible. The team can say: “We reduced methods above cognitive complexity 15 from 23 to 12 in two months. At this rate, we reach 5 in six weeks.” The measurement creates accountability, direction, and evidence for continued investment.

The Before

// HARD TO READ: No metrics tracked over time.
// Improvement is based on gut feeling.
// The team cannot demonstrate progress to stakeholders.

// SonarQube runs in CI but nobody tracks trends.
// ArchUnit tests exist but nobody counts baseline violations over time.
// PR review time is not measured.
// Onboarding time is anecdotal.

The Fix

Five metrics that capture readability improvement. Track them weekly.

1. Cognitive complexity hotspot count Number of methods with SonarQube cognitive complexity above 15. The threshold that predicts review difficulty. This number should decrease monotonically. If it increases, a hotspot was added or an existing one got worse. Investigate.

SonarQube provides this through its web API:

# Query SonarQube for methods above complexity threshold
curl -s "https://sonar.example.com/api/measures/component_tree?\
component=com.logitrack&\
metricKeys=cognitive_complexity&\
metricSort=cognitive_complexity&\
metricSortFilter=withMeasuresOnly&\
s=metric&\
asc=false&\
ps=50" | jq '.components[] | select(.measures[0].value | tonumber > 15)'

2. ArchUnit violation count (from frozen baseline) Number of remaining violations in the ArchUnit freeze file. Each fixed violation reduces this count. Each new violation is blocked by CI. This number decreases over time and never increases.

// ArchUnit freeze files are stored in src/test/resources/archunit_store/
// Count remaining violations:
// wc -l src/test/resources/archunit_store/*.txt

// Track the total across all freeze files per sprint.
// The total should decrease monotonically.

3. Public class ratio Percentage of classes that are public out of total classes. After the visibility audit from Chapter 6, this ratio decreases as implementation classes become package-private. A lower ratio means a smaller public API surface, which means fewer possible inter-package dependencies.

// Count public vs total classes
@Test
void track_public_class_ratio() {
    JavaClasses classes = new ClassFileImporter()
        .importPackages("com.logitrack");

    long total = classes.size();
    long publicCount = classes.stream()
        .filter(JavaClass::isPublic)
        .count();

    double ratio = (double) publicCount / total * 100;
    System.out.printf("Public class ratio: %.1f%% (%d/%d)%n",
        ratio, publicCount, total);
    // Record this number weekly
}

4. Largest class method count The number of public methods on the largest class. This tracks God class decomposition progress. The number should decrease as responsibilities are extracted.

5. Median PR review time Measured from GitHub PR metadata. As the codebase becomes more readable, reviews become faster because reviewers spend less time understanding the code and more time evaluating the change. This metric captures the readability improvement as experienced by the team.

# Query GitHub API for PR review times
# (time from PR creation to first review)
gh pr list --state merged --limit 50 --json number,createdAt,reviews \
  | jq '[.[] | {
      number: .number,
      created: .createdAt,
      firstReview: .reviews[0].submittedAt,
      hoursToReview: ((.reviews[0].submittedAt | fromdate) -
                      (.createdAt | fromdate)) / 3600
    }] | sort_by(.hoursToReview) |
    .[length/2] | .hoursToReview'

Post these five numbers on a team dashboard updated weekly. Share the dashboard with stakeholders. The numbers tell the story: the codebase is becoming easier to read, review, and modify. The investment in readability improvement has a measurable return.

The Rule

Track five metrics weekly: hotspot count, ArchUnit violations, public class ratio, largest class size, and median review time. Post them on a visible dashboard. If any metric gets worse for two consecutive sprints, investigate. The metrics serve two purposes: they guide the team’s improvement effort toward the areas with the highest impact, and they provide evidence to stakeholders that the improvement is real and ongoing. Unmeasured improvement is invisible improvement. Invisible improvement loses funding. Measure what matters and make the numbers visible.