Engineering Metrics FAQ
Definitions, formulas, and DORA benchmark tiers for every metric FlowMetrics tracks — plus how to read your value stream map.
Lead Time
Total time from when a pull request is opened to when it is merged into the main branch.
lead_time = merged_at − created_at
Why it matters
Lead Time is the single most important measure of delivery speed. When a CEO asks "why is engineering so slow?", lead time is the number that answers it. Short lead times mean feedback loops are tight: bugs get caught faster, features reach customers sooner, and engineers spend less time maintaining context across long-lived branches.
DORA benchmark tiers
| Tier |
Lead Time for Changes |
| Elite |
Less than 1 day |
| High |
1 day to 1 week |
| Medium |
1 week to 1 month |
| Low |
More than 1 month |
Source: DORA State of DevOps Report
Time to First Review
How long a pull request sits before any reviewer leaves a comment or submits a review.
time_to_first_review = first_review_at − created_at
Why it matters
A pull request waiting for its first review is blocked work. The longer it waits, the more likely the author has moved on to something else — making a review harder to act on and increasing the cost of context switching. Time to First Review is the most direct signal of whether your review culture is responsive.
Industry benchmarks
| Performance |
Time to First Review |
| Best in class |
Under 4 hours |
| Good |
Under 1 day |
| Improving |
1–3 days |
| Needs attention |
Over 3 days |
Derived from industry surveys and engineering productivity research.
Change Failure Rate
The percentage of merged pull requests that were remediations — hotfixes or reverts of previous changes.
change_failure_rate = remediation PRs ÷ all merged PRs
Why it matters
Change Failure Rate measures quality at the system level — not individual bugs, but how often the overall delivery process produces work that needs to be undone. A high CFR means your team is spending engineering time fixing production instead of shipping features. FlowMetrics detects remediations automatically by looking for "hotfix" or "revert" in PR titles and branch names.
DORA benchmark tiers
| Tier |
Change Failure Rate |
| Elite |
0–5% |
| High |
5–10% |
| Medium |
10–15% |
| Low |
Over 15% |
Source: DORA State of DevOps Report
Change Request Rate
The percentage of merged pull requests that received at least one "Changes Requested" review before merging.
change_request_rate = PRs with changes-requested ÷ all merged PRs
Why it matters
Change Request Rate measures rework — how often code needs to be sent back before it's acceptable. Some rework is healthy: it means reviewers are engaged and catching real issues. Very high rates may indicate unclear requirements, weak pre-review practices, or reviewers with different quality expectations. Unlike Change Failure Rate (production failures), this tracks issues caught before merge.
Industry context
| Performance |
Change Request Rate |
| Low rework |
Under 20% |
| Moderate rework |
20–40% |
| High rework |
Over 40% |
Industry-derived. No universal standard exists; use as a relative baseline for your own team over time.
Work In Progress (WIP)
The daily count of pull requests that were open on a given date — created before the date and not yet closed or merged by that date.
wip(date) = PRs where created_at < date AND (closed_at IS NULL OR closed_at > date)
Why it matters
High WIP is the enemy of fast delivery. By Little's Law, cycle time increases proportionally with WIP — the more things in flight at once, the slower each one moves. WIP growth over time is a leading indicator: before lead times worsen, you'll often see WIP climbing first. Tracking daily WIP helps identify whether the team is starting more than it finishes.
Guidance
There is no universal WIP target — it depends on team size. The goal is a stable or declining WIP trend over time. A rising WIP trend for more than 2–3 weeks signals a flow problem worth investigating.
Cumulative Flow Diagram (CFD)
A daily stacked area chart showing the count of pull requests in each lifecycle stage: In Dev, In Review, Ready to Deploy, and Done.
In Dev: created_at set, no first_review_at, not merged/closed
In Review: first_review_at set, no first_approval_at, not merged/closed
Ready to Deploy: first_approval_at set, not merged/closed
Done: merged or closed
Why it matters
The CFD is the most diagnostic view in FlowMetrics. When a band on the chart gets wider over time, that stage is a bottleneck — work is entering it faster than it's leaving. A widening "In Review" band means reviewers are the constraint. A widening "Ready to Deploy" band means the deployment or merge process is the constraint. In a healthy system, all bands grow at roughly the same rate and the overall shape is stable.
Reading the diagram
- The vertical distance of any band at a given date = the count of PRs in that stage on that day.
- A band that stays constant in height = healthy, balanced flow through that stage.
- A band that grows = PRs are accumulating faster than they're moving forward.
- Sudden steps down = batch processing (e.g., a Friday review sweep) rather than continuous flow.
Value Stream Map
A breakdown of where merged pull requests spent their lead time, across a workflow you define. Each state is entered by a GitHub event — a label, a draft, the first review, a changes-requested review, or an approval — and is marked as either work or wait.
share_of_lead_time(state) = Σ time in state ÷ Σ lead time (created → merged)
flow_efficiency = time in work states ÷ (time in work states + time in wait states)
rework_rate = PRs that moved back to an earlier state ÷ merged PRs
Why it matters
Lead time tells you how long delivery takes; a value stream map tells you why. Most of a PR's life is usually spent waiting — for a reviewer, for a re-review, for someone to hit merge. Separating work from wait shows whether you need faster people or a faster system, and the state holding the largest share of lead time is flagged as the likely bottleneck. Time in each state is reported as a median and P75, never an average.
Reading the map
- Low flow efficiency (under ~25%) is common and means queues, not effort, dominate lead time.
- A wait state with a large share of lead time is a queue worth attacking first — often "awaiting review."
- A rising rework rate means PRs are bouncing back after review; look at PR size and how clear requirements are.
- States reflect labels and review events, not hands-on time, so treat flow efficiency as an estimate and watch the trend.
Peer Benchmarks
How a repository compares with teams of a similar size on six metrics over the last 28 days: lead time, time to first review and time to first approval (all P50), change request rate, PR size (P50 lines changed) and merged PRs per author.
peer_group = repositories with the same number of active authors (1–5, 6–15, 16–50, 51+)
position = share of the peer group this repository does better than (0–100)
Why it matters
Your own trend shows whether you're improving, but not whether 20 hours to a first review is normal for a team like yours. Peer benchmarks answer that. A metric in the slowest quarter of its peer group is the clearest place to start, so FlowMetrics calls it out in your summary and next to the metric.
How the comparison works
- Peer groups start with active, review-based open-source projects. Customer teams are compared with each other once enough teams of a size have joined.
- Bots such as Dependabot and Renovate are left out, and a repository needs at least 10 human-merged PRs in the last 28 days to be ranked.
- A comparison is only published when it combines at least 10 repositories from at least 5 organizations. It never includes repository names, people, pull request titles or code.
- Organization admins can stop contributing their data at any time in billing settings, and still see their own benchmarks. Read the privacy details.
- Benchmarks are included in Pro, Business, Enterprise and every free trial.
Stop guessing. Start measuring.
Connect your GitHub account and have answers in minutes.
Generate Your Dashboard →
Reads pull request metadata only. We cannot read your source code.