How to Track Code Quality Metrics
This guide explains how to track code quality metrics using a repeatable system for choosing, connecting, and acting on the signals that correlate with fewer incidents and faster delivery. It starts with defining outcome versus process metrics so your team tracks what actually matters, not just what's easy to measure.
Most engineering teams fall into one of two traps when it comes to code quality: they track nothing and rely on gut feel, or they track everything and drown in dashboards nobody reads. Neither gives you a real signal. This guide walks through a repeatable system for choosing, connecting, and acting on code quality metrics that actually correlate with fewer incidents and faster delivery. Before you start, you'll need admin access to your GitHub or GitLab organization and your Linear (or Jira) workspace, plus a short conversation with your team about what "quality" means for your specific product. Skip that conversation and every metric you pick afterward will feel imposed rather than owned.
Step 1: Define what quality means for your team
Before you touch a single tool, separate two categories of metrics: outcome metrics and process metrics. Outcome metrics measure what actually happened to the product, things like defect escape rate (bugs that reach production) or incident count. Process metrics measure how the work got done, like review turnaround time or code churn. Both matter, but they answer different questions. Outcome metrics tell you whether quality is actually improving. Process metrics tell you why.
The most common mistake at this stage is defaulting to metrics that are easy to pull but meaningless, lines of code shipped, commit count, or number of PRs merged per engineer. These reward activity, not quality. A developer can inflate every one of these numbers while shipping worse code, and a team that ships fewer, better-scoped commits will look "less productive" by these measures while actually outperforming on real outcomes. If your tracking system rewards volume, you'll get volume, not quality.
Instead, ask a more specific question: what does a quality failure look like on your team? For a payments startup, it might be a transaction bug that reaches production. For a dev-tools company, it might be a regression that breaks a customer's CI pipeline. Write that down before you pick a single metric.
Bring engineers into this conversation early, not after the metrics are already chosen. If tracking rolls out as something decided in a leadership meeting and imposed top-down, it reads as surveillance, and you'll get gamed numbers and quiet resentment instead of honest signal. If engineers help define what "quality" means for the product they're building, they're far more likely to treat the resulting metrics as useful feedback rather than a scorecard to defend against. This single step determines whether everything that follows actually works.
Step 2: Pick a core metric set instead of tracking everything
Once you've agreed on what quality means, resist the urge to instrument everything at once. Start with a small, deliberate set. A reasonable starting point for most startup teams includes:
- Code churn: the percentage of code rewritten or deleted within two to three weeks of being written, a strong early indicator of unclear requirements or rushed implementation.
- PR review turnaround time: how long a pull request sits before it gets meaningful review, a proxy for both process friction and review quality.
- Change failure rate: the percentage of deployments that cause a failure in production, one of the four DORA metrics.
- Defect or bug reopen rate: how often "fixed" issues come back, a signal that root causes aren't being addressed.
The DORA metrics, deployment frequency, lead time for changes, change failure rate, and time to restore service, come from Google Cloud's DevOps Research and Assessment program and remain a solid industry reference point for engineering performance. They're worth using as a starting framework, but treat any specific benchmark numbers you find with caution and check the current DORA reports for teams at your size and stage before comparing yourself against them. A five-person seed-stage team and a 200-engineer Series D company have very different "elite performer" thresholds.
Cap your initial list at four to six metrics total. This isn't an arbitrary constraint. Every metric you add past that point competes for attention in your weekly rituals and dilutes focus on the ones that matter most. Teams that try to track fifteen metrics from day one typically end up reviewing none of them consistently. Start narrow, prove the system works, and expand deliberately later if a genuine gap shows up.
Step 3: Connect your source data instead of building manual reports
With your metric set defined, the next decision is how you'll actually capture the data. The raw signal already exists in the tools your team uses every day: commit and PR history in GitHub or GitLab, cycle time and issue data in Linear or Jira, and build and test results in your CI/CD pipeline. The question is whether you pull it manually or connect it continuously.
Manual tracking, someone exporting PR data into a spreadsheet once a sprint, works for a team of three. It breaks down almost immediately past that. Once you have multiple repos, multiple squads, and more than a handful of engineers, the manual approach either consumes hours of someone's week or quietly stops happening after the second sprint. Custom scripts pulling from the GitHub API are a step up, but they require ongoing maintenance as your workflows evolve, and they still leave you to build the analysis layer yourself.
This is where an engineering intelligence platform earns its place. Progress, for example, connects directly to GitHub and Linear and continuously ingests commit, PR, and issue activity without requiring your team to build or maintain custom tooling. The distinction that matters here isn't just data collection, though. It's whether the tool does anything with the data once it has it.
When you evaluate a platform for this step, check specifically whether it computes metrics automatically, churn, merge volume, stalled work, review latency, or whether it just hands you raw activity logs you still have to analyze yourself. Plenty of tools call themselves "engineering analytics" while really just aggregating dashboards and leaving the interpretation to you. Progress is built to do the interpretation: it pre-computes operational signals like stalled work and rising churn rather than leaving you to eyeball a chart and guess whether a number is a problem. That difference is what determines whether this system survives past the first month or turns into another dashboard nobody opens.
Step 4: Set baselines before setting targets
Once data is flowing, the temptation is to immediately set targets: "review turnaround should be under 24 hours" or "churn should stay below 15%." Resist this for at least two to four weeks. You need a baseline before a target means anything, because your team's current normal might look nothing like what a generic benchmark suggests. A five-person startup team's "normal" PR review time is going to differ meaningfully from a 100-engineer org's, and neither is inherently right or wrong.
During this baseline period, segment the numbers by team or by area of the codebase rather than looking at one company-wide average. A legacy payments module that rarely changes will show very different churn and review patterns than a new feature branch under active development, and averaging them together hides both. If you set a single blended target too early, you'll either set it too loose for the risky areas or too strict for the stable ones.
Use this window to observe, not to judge. Look for repos or squads that already show warning signs, rising churn, slowing merge cadence, PRs sitting unreviewed for days, before you've even set a formal target. Those early signals often point to exactly the areas that need attention first, and they give you a far more grounded starting point for setting realistic goals than any industry benchmark could.
Step 5: Automate alerts for stalled work and rising risk
Baselines and targets are only useful if someone notices when a metric moves. Waiting for a sprint retro to catch a churn spike or a stalled PR means the problem has already been live for a week or two. The fix is configuring automatic alerts tied to the thresholds you set in Step 4: flag churn when it spikes above baseline, flag PRs stalled past a set number of days, flag merge volume that's creating deployment risk across a release window.
The quality of the alert matters as much as its timing. A raw dashboard that shows a churn graph trending upward still requires someone to interpret it, decide if it's a problem, and figure out what to do next. Pre-computed operational signals skip that interpretation step. This is a meaningful part of what Progress does differently: instead of a chart you have to read, it surfaces a direct assessment, "this initiative is at risk," "this repo shows rising change-pressure," so a lead can act instead of first having to diagnose whether the number is even worth worrying about.
Just as important is where the alert goes. A risk signal posted into a busy shared Slack channel with fifty other notifications gets ignored. Route alerts to the person who can actually act on them: a stalled PR alert to the reviewing engineer's tech lead, a rising change-failure-rate alert to the eng manager overseeing that team's deployment cadence. Matching the alert to the right owner is what separates a system people respond to from one they mute within a week.
Step 6: Build metrics into weekly rituals
A metrics system that only gets reviewed during quarterly planning is a metrics system that isn't really running. Build a short, recurring check into an existing ritual, sprint planning or your weekly engineering sync, and keep it genuinely short. Five minutes, two or three metrics, no more. The goal is a quick pulse check, not a status-theater exercise where everyone recites numbers that don't change anyone's decisions.
Pair the quantitative check with a qualitative one on team momentum and morale. This is the part most quality-tracking systems miss entirely. A team's churn and review-time numbers can look perfectly healthy while the team itself is quietly burning out, stalling on decision-making, or losing confidence in a project's direction, none of which shows up in a code metric until it's already affecting delivery. Progress includes momentum and morale reads alongside its operational signals specifically because the human layer tends to move before the numbers do, and catching it early gives leads a chance to intervene before it shows up as a delivery problem.
When it's time to report upward, avoid having your team spend an afternoon assembling slides from scratch every sprint. An on-demand executive summary, something Progress generates directly from the underlying activity data, gives leadership a current, accurate picture without pulling an engineer off real work to build it. That time savings compounds: a five-minute weekly ritual for the team, and a summary leadership can request whenever they need it, rather than a recurring reporting tax on your best people.
Step 7: Revisit and adjust metrics quarterly
Every metric you track long enough eventually runs into Goodhart's Law: once a measure becomes a target, it stops being a reliable measure. If PR review turnaround time becomes the one number leadership watches closely, don't be surprised when reviews start getting rubber-stamped to hit the target, technically fast, substantively worthless. This isn't a hypothetical risk, it's the predictable result of optimizing for a proxy instead of the outcome it was meant to represent.
Set a quarterly review of your metric set specifically to catch this. Ask whether each metric still correlates with a real outcome you care about. Sometimes a number improves for the wrong reason: churn dropping because a repo is being actively neglected rather than because code quality actually improved, for instance. A metric that's stopped reflecting reality is worse than no metric at all, because it creates false confidence.
Use this checkpoint to spot-check your numbers against what's actually happening day to day. Tools that support natural-language queries against your engineering activity make this easier: Progress's MCP server and Claude integration let you ask direct questions, like which repos have seen rising churn without a corresponding increase in review depth, and get an answer grounded in real activity rather than a metric you have to trust blindly. Retire metrics that have stopped earning their place, and don't be afraid to swap in a new one if your team's risk profile has shifted since the last quarter.
Keeping the system honest as you scale
The system you've built here isn't static. As your team grows and your codebase matures, the metrics that mattered at ten engineers won't necessarily matter at fifty, and a baseline set six months ago may no longer reflect reality. Periodically check that your metric set still ties back to outcomes you actually care about, fewer production incidents, faster and more predictable delivery, a team that isn't quietly burning out. If a metric can't answer "so what" in one sentence, it's probably time to retire it.
Treat this less as a one-time setup and more as infrastructure you maintain alongside your codebase itself. Learn more about our services if you want a platform that handles the data connection, the risk signals, and the reporting layer for you, so your team spends its time acting on quality issues instead of assembling the system to find them.