PR Lifecycle Metrics
Last updated: October 27, 2026
PR Lifecycle splits the time a merged pull request (PR) took, from its first commit to merge, into four stages: Coding, Awaiting First Review, Reworking, and Idling. A fifth stage, Deploying, runs from merge to the first production deployment that includes the PR, for organizations where Span links deployments to PRs.
Why it matters
Total cycle time tells you that work is slow. The stages tell you where it waits: before the PR is ready, in the review queue, in back-and-forth, or after the last action before merge. Each stage points to a different fix, so you can work on the wait that costs the most.
How it works
Span reads PRs, commits, review requests, ready-for-review events, reviews, and comments from your Git platform and records these events for each merged PR:
Event | How Span sets it |
|---|---|
First Commit | The earliest author date among the PR's commits. Merge commits, commits by ignored Git usernames, and commits Span can't match to a known Git account don't count. If the earliest commit is later than PR Opened, Span uses the PR's creation time instead. |
PR Opened | When the PR became ready for review. Span uses the first of these that exists, in this order: the first reviewer request, the last time the PR left draft, the PR's creation time. |
First Review | The earlier of the first review (any state) and the first comment from someone other than the author. |
Last Action | The later of the last commit and the last review or comment. |
Merge | The merge time from your Git platform. |
In Production | The completion time of the first successful production deployment that includes the PR (Deploying stage only). |
The stages run between those events:
Stage | Runs from | What a long stage usually means |
|---|---|---|
Coding | First Commit to PR Opened | Large or long-running changes, or local work done well before the PR opened |
Awaiting First Review | PR Opened to First Review | Review capacity or assignment gaps |
Reworking | First Review to Last Action | Unclear requirements, large diffs, or slow follow-up between author and reviewer |
Idling | Last Action to Merge | CI, merge queues, required checks, or nobody pressing merge |
Deploying | Merge to In Production | Infrequent releases or a backlog of merged work waiting to ship |
Span measures elapsed clock time between events, including nights. If your organization excludes weekends, Span removes Saturdays and Sundays using your organization's time zone. Span stores each value in seconds and shows hours or days. Each PR lands on its merge date.
Aggregations. Pick how Span rolls up the PRs in each period in Page settings:
Option | What it shows |
|---|---|
Trimmed Average (default) | The mean after capping each PR at 30 days. No PR is removed. |
Median (P50) | The middle PR: half are faster, half are slower. |
75th Percentile (P75) | The value 75% of PRs are at or below. |
90th Percentile (P90) | The value 90% of PRs are at or below. |
Max | The slowest PR. |
Only the Trimmed Average uses the 30-day cap. Percentiles and Max use raw values, and each percentile returns one real PR's value. Count metrics such as Total PRs Merged show totals and don't use aggregations.
Reference ranges. These are starting points, not rules. Compare against your own baseline.
Stage | Healthy | Worth a look |
|---|---|---|
Coding | P50 about 1 hour, P75 4 to 8 hours | P90 well above 24 hours |
Awaiting First Review | P50 about 4 hours, P75 under 48 hours (the default Time to First Review target) | P75 above 48 hours; above 72 hours is critical |
Reworking | Under 2 hours excellent, 2 to 8 hours good | 1 to 2 days concerning, over 2 days poor |
Idling | Under 1 hour excellent, 1 to 4 hours good | Over 24 hours |
Setup
Go to Insights → Productivity → Velocity → PR lifecycle.
Drag the range slider to pick any pair of events, for example PR Opened to Merge. The default range is First Commit to Merge.
Choose an aggregation in Page settings.
Click a point on a chart to open the PRs behind it.
To see the Deploying stage:
Send production deployments to Span from your CI, through the DORA API or a
$deployevent. Span's Git connectors don't create deployment records.Ask your Span account team to turn on deployment-to-PR linking and the Deploying stage. Span turns these on for your organization on request.
Once at least one merged PR has a linked production deployment, the page shows the Deploying stage and the In Production event, and the default range becomes First Commit to In Production.
Things to know
Worked example: commits authored Monday 10:00 and Tuesday 15:00. The PR opens as a draft Tuesday 16:00 and is marked ready Wednesday 09:00, with no reviewer request. A teammate reviews Wednesday 14:00, the author pushes a fix Thursday 11:00, the teammate approves Thursday 13:00, and the PR merges Friday 10:00. Cycle time is 96 hours: Coding 47, Awaiting First Review 5, Reworking 23, Idling 21.
Trimmed Average example: PRs of 2, 5, 35, and 50 days count as 2, 5, 30, and 30. The Trimmed Average is (2 + 5 + 30 + 30) ÷ 4 = 16.75 days. A plain average would be 23 days.
Draft PRs: on GitHub, GitHub Enterprise Server, and GitLab, draft time counts as Coding until someone requests a reviewer or marks the PR ready. A reviewer requested while the PR is still a draft sets PR Opened at that moment. On Azure DevOps, PR Opened is the creation time, so draft time counts as Awaiting First Review. On Bitbucket Cloud, a PR opened with reviewers gets PR Opened at creation, draft or not.
Reviewer requested late: because a reviewer request wins over the ready-for-review event, a non-draft PR whose reviewer was requested two days after creation gets two extra days of Coding.
Who counts as a reviewer: anyone other than the PR author, including people who weren't asked to review. Bots, coding agents your organization set up as dev agents, and ignored Git usernames don't count. When a PR has a reviewer request, reviews and comments before the first request don't count. Approvals, change requests, and plain comments all count.
PRs with no review: they still have a cycle time. Awaiting First Review and Reworking stay empty, and Idling runs from the last commit to merge.
Idling isn't tied to approval: it starts at the last action of any kind. CI runs, merge queues, and required checks after the last action count as Idling.
Comments after merge: Span doesn't stop counting at merge. A comment after merge moves Last Action past the merge, which stretches Reworking and sets Idling to 0.
Closed and reopened PRs: Span keeps the PR's full history. Time while the PR sat closed still counts, and the review clock doesn't pause. The PR lands on its final merge date.
Stages don't add up to the total: Span computes each stage as its own metric over the PRs that have that stage, and caps each stage at 30 days separately. Events can also overlap: a comment left before the PR was ready makes Awaiting First Review 0 while Coding still runs.
Weekends: with weekends excluded, Span subtracts 24 hours for each Saturday and Sunday between the two dates. A PR opened Friday 17:00 and merged Monday 09:00 shows 16 hours. A stage that starts and ends inside one weekend has no value.
Deploying counts production only: only successful deployments count. Production means the environment name is blank or contains "prod" or "prd", ignoring case, so "pre-prod" counts. When a deployment doesn't list its PRs, Span infers them from PRs merged to the default branch since the previous deployment to the same repository and environment. Deploying an older build gives that deployment and the next one the wrong set of PRs.
Unmerged and reverted PRs: open, closed-unmerged, and reverted PRs don't count. A revert PR that merges counts as its own PR.
History can change: Span recalculates from the full history, so changing the weekend setting, ignore lists, or a person's contributor flag changes past values.
Related articles
PR Cycle Time Threshold Filter
Review Response Time (Average)
How to setup weekend exclusion for metrics
Lead Time to Production in Span
How to use the DORA API to send deployment activity to Span
Need help?
Contact your Span account team or reach out to support@span.app.