Pull Request Cycle Time Calculator
Measure pull request cycle time from PR timestamps, compare review pickup delays and slow-tail percentiles, and spot rows that need cleanup.| {{ header }} | Copy |
|---|---|
|
No {{ tab.label.toLowerCase() }} rows
Paste merged PR rows or load the sample source before exporting this table.
|
|
| {{ cell.value }} {{ cell.value }} |
Introduction:
Review queues slow down delivery long before a release dashboard shows trouble. A pull request can look small, pass tests, and still sit for days because nobody picked it up, the author kept revising a draft, an approval waited on one person, or the final merge was postponed after review. Pull request cycle time turns that waiting into an elapsed-time measure that a team can compare across review windows.
In most engineering conversations, PR cycle time means the time from a chosen pull request start point to merge. The start point deserves care. Counting from creation includes draft time, early feedback, and author-side preparation. Counting from ready-for-review focuses the number on reviewer pickup and merge flow, but it can hide long draft periods if teams open draft PRs very early.
| Timing concept | What it asks | Common mistake |
|---|---|---|
| Created to merge | How long the pull request existed before it merged. | Comparing teams with very different draft habits. |
| Ready for review to merge | How long review and merge took after the author signaled readiness. | Forgetting rows that do not record a ready timestamp. |
| First review wait | How long the author waited for the first reviewer signal. | Treating slow pickup as the same problem as slow approval. |
| Approval to merge | How much time remained after approval before the code merged. | Blaming reviewers when the delay is merge ownership, CI, or release timing. |
Averages are useful, but they are not enough for review work. One stale PR can disappear inside a busy month, and one emergency fix can make the average look healthier than the normal queue feels. Percentiles such as P85 and P95 show the slow tail, which is the older slice of completed PRs that usually causes context switching, stale approvals, merge conflicts, and repeated re-review.
PR cycle time is related to DORA change lead time, but the two measures answer different questions. Change lead time follows a change through production deployment. Pull request cycle time stops at merge, so it is better suited to reviewer routing, PR size, draft policy, and handoff habits inside the code review process.
Useful comparisons keep scope narrow. A single repository, service, or review lane usually produces a stronger signal than a mixed export containing unrelated teams, time zones, emergency fixes, generated-code changes, and abandoned old PRs. The number should start a review discussion, not replace one.
How to Use This Tool:
Use one reporting lane at a time, then set the timestamp rule before judging targets or charts. The summary updates from the pasted rows, and red or yellow messages should be fixed or carried into the interpretation.
- Enter Repository or team so copied rows, downloaded tables, and JSON output can be traced back to the service or review lane being measured.
- Choose Cycle start. Use Created when the full PR lifetime matters, or Ready for review when draft time should not count against the reviewer queue.
- Set Cycle target and Review pickup target in hours. These values control target-miss labels, summary badges, and chart reference lines.
- Paste rows into Pull request rows, browse for a CSV or TXT file, drop a file onto the textarea, or load the sample. Headered CSV can include
pr,created_at,ready_at,first_review_at,approved_at,merged_at,status, andlines_changed. Three-column rows are read as PR, created time, and merge time. - Use Normalize after pasting uneven rows if you want a consistent header and timestamp layout. If the page shows Review PR input, add valid
created_atand at least one usablemerged_at. If it shows Data quality notes, check fallback starts, skipped rows, hidden parser notes, or timestamps that appear out of order. - Open Cycle Time Ledger first. Confirm each PR's Started, First review, Merged, Cycle time, Pickup wait, Target signal, and Review note.
- Use Review Queue Brief, Cycle Target Chart, Review Stage Mix Chart, and JSON after the source rows and targets match the review window you plan to discuss.
Interpreting Results:
The headline number is average cycle time for merged PRs. Read it next to P85, target miss rate, and the open count. A low average with high P85 means the normal PR may move through review quickly while the slowest slice still needs active attention. A high open count means the completed sample may not match the queue reviewers are dealing with today.
Badge language is deliberately modest. Average on target means the mean completed cycle is within the selected cycle target. Tail on target means P85 is within that same target. Pickup aligned means median first-review wait is within the pickup target, or there is not enough first-review data to show a pickup delay.
| Signal | What it means | What to check next |
|---|---|---|
| Over target | A merged PR took longer than the selected cycle target. | Compare pickup wait, review or approval time, and approval-to-merge time for that row. |
| Pickup slow | First review wait exceeded the pickup target while the full cycle stayed within the cycle target. | Check reviewer ownership, code-owner routing, notification habits, and workday coverage. |
| Open | The row has no usable merge timestamp and is excluded from completed-cycle statistics. | Review open PR age separately or rerun the export after those PRs merge. |
| Invalid cycle | The merge timestamp is before the selected start timestamp. | Fix timezone conversion, swapped columns, or source export errors before trusting that row. |
A good cycle-time snapshot does not prove review quality, test strength, deployment readiness, or customer impact. Pair it with review comments, CI results, defect trends, and production delivery metrics before changing staffing rules or merge policy.
Technical Details:
Completed-cycle statistics use rows with a valid start timestamp and a merge timestamp at or after that start. Rows without a merge timestamp remain useful queue context, but they do not belong in average, median, P85, or P95 because their final duration is still unknown.
The chosen start rule changes the measurement basis. Created-to-merged includes draft time and early waiting. Ready-to-merged uses the ready timestamp when that value is present, then falls back to creation time for rows that do not include it. That fallback keeps the row visible while raising a data-quality note.
Formula Core:
Cycle duration is elapsed time from the selected start to merge, expressed in hours. Percentiles are computed from sorted completed-cycle values with interpolation between neighboring rows when the rank does not land on one exact row.
A row that starts at 09:00Z and merges at 18:30Z on the same day has a 9.5 hour cycle. If the cycle target is 24 hours, that row is inside target; if first review happened at 13:20Z, its pickup wait is 4.3 hours and can be judged against the pickup target separately.
| Measure | How it is formed | Why it matters |
|---|---|---|
| Cycle time | Selected start timestamp to merge timestamp. | Shows elapsed review-and-merge time for one completed PR. |
| Average | Mean of valid completed-cycle hours. | Useful as a center point, but sensitive to a few very slow rows. |
| Median | 50th percentile of completed-cycle hours. | Shows the middle completed PR without letting one stale row dominate. |
| P85 and P95 | Interpolated tail percentiles from sorted completed cycles. | Expose slow-tail pressure even when the average stays acceptable. |
| Pickup wait | Selected start to first review, or approval if approval is the first review-like timestamp available. | Separates reviewer pickup delay from later review and merge work. |
| Target miss rate | Merged PRs over the cycle target divided by merged PRs. | Turns the target into a queue-health signal instead of one threshold line. |
Review-stage timing decomposes the same completed cycle. Pickup wait runs from start to the first review signal or approval. Review or approval time starts at that first review signal and ends at approval when approval exists inside the cycle, otherwise it can run to merge. Approval-to-merge time covers the final tail. Any completed-cycle time not explained by those timestamps is kept as unattributed time rather than guessed.
| Condition | Result | Reason |
|---|---|---|
| Missing or unreadable created time | Row is skipped with a warning. | No reliable start timestamp exists. |
| Ready mode with no ready time | Created time starts the cycle and a warning is shown. | The row remains comparable enough to inspect, but its basis is mixed. |
| No merge time | Row appears as open and is excluded from completed-cycle metrics. | The final duration is unknown. |
| Merge before selected start | Row is marked invalid and excluded from completed-cycle metrics. | Negative elapsed time usually means bad timezone conversion or swapped columns. |
| Review timestamp outside the cycle window | A warning is shown and stage timing avoids that impossible value. | Stage math should not silently accept review events outside start-to-merge time. |
Fair comparisons need the same start rule, target hours, source columns, and reporting lane across runs. Mixing created-based and ready-based windows, or mixing repositories with different review policies, can make a real process change look like a measurement change.
Privacy and Accuracy Notes:
The calculator works in the browser from the pasted text or selected CSV/TXT file. That reduces unnecessary upload for sensitive repository data, but copied tables, downloaded files, screenshots, and shared page URLs can still disclose PR names, timestamps, and team context.
- Review rows before sharing exports, especially when PR titles, identifiers, or repository names reveal unreleased work.
- Use ISO-style timestamps with time zones when possible. Date-only or timezone-stripped exports can shift durations across workdays.
- Keep old abandoned PRs separate from normal reporting unless the goal is to quantify cleanup debt.
Worked Examples:
A checkout service export has four merged PRs with cycle times of 9.5, 12.0, 24.0, and 49.3 hours against a 24 hour Cycle target. Average cycle time is about 23.7 hours, but P85 is above target because the slowest PR stretches the tail. The useful follow-up is not the average alone; inspect the slow PR's Pickup wait, Review note, and stage mix.
A team that opens drafts early switches Cycle start to Ready for review. Three rows include ready_at, but one older export does not. That row still appears in Cycle Time Ledger using created time as the start, and Data quality notes records the fallback. Keep that caveat attached when comparing this run with a cleaner future export.
A review manager drops in a three-column CSV with PR, created time, and merge time. The page can calculate Cycle time, Average, and P85, but Pickup wait remains unavailable because no first-review or approval timestamp exists. The cycle-time number is still useful, but it cannot say whether delay came from reviewers or from the final merge step.
A troubleshooting case starts with a row whose merge timestamp is before the selected start. The row receives Invalid cycle and is excluded from completed-cycle statistics. Correct the timezone, timestamp order, or column mapping before using the average and percentile figures.
FAQ:
Should draft time count in PR cycle time?
Count draft time with Created when you want the full pull request lifetime. Use Ready for review when drafts are common and the review queue should start only after the author asks for feedback.
Why are open PRs excluded from the average?
Open rows do not have a completed merge timestamp, so their final cycle time is unknown. They appear as queue context, but including them in a completed-cycle average would understate long-running work.
What is the difference between cycle time and pickup wait?
Cycle time runs from the selected start to merge. Pickup wait runs from the selected start to the first review signal, or to approval when approval is the first review-like timestamp available.
Why does the source warning mention fallback start time?
Ready for review mode uses ready_at only when the row includes it. If that timestamp is missing, the row falls back to created_at and the warning keeps the mixed basis visible.
Can this replace DORA change lead time?
No. PR cycle time stops at merge. DORA change lead time follows a change to production deployment, so use this calculator for review flow and deployment metrics for the rest of the delivery path.
Glossary:
- Cycle time
- Elapsed time from the selected pull request start to merge.
- Pickup wait
- Elapsed time from the selected start to the first review signal or approval.
- P85
- The 85th percentile of completed-cycle hours, used to show slow-tail pressure.
- Target miss rate
- The share of merged pull requests whose cycle time exceeded the selected cycle target.
- Unattributed time
- Completed-cycle time not explained by pickup, review or approval, and approval-to-merge timestamps.
References:
- DORA's software delivery performance metrics, DORA.
- About pull request reviews, GitHub Docs.
- Merge request analytics, GitLab Docs.
- Pull request cycle time, Swarmia.