A Ruby script to analyze GitHub Pull Request review latency metrics and export the data to CSV files for analysis in Excel or other tools.
# Get a GitHub token from https://github.com/settings/tokens (needs 'repo' scope)
export GITHUB_TOKEN=ghp_xxxxxxxxxxxx
# Run the analysis (analyzes all merged PRs since 2008-01-01)
./run myorg/myrepo
# Or specify a start date (analyzes from August 1st until now)
./run myorg/myrepo 2025-08-01
# Or with a specific date range
./run myorg/myrepo 2025-11-01 2025-11-30This will generate two CSV files: pr_first_review.csv and pr_rereview_cycles.csv
PRcrastinate helps you understand how long it takes for PRs to get reviewed in your repository by tracking:
- Time from PR creation to first review
- Time from review request to first review
- Time from last commit to first review
- Re-review cycles after changes are requested
- Docker
- A GitHub Personal Access Token
-
Go to GitHub Settings: https://github.com/settings/tokens
-
Click "Generate new token" → "Generate new token (classic)"
-
Give your token a descriptive name (e.g., "PR Review Latency Analysis")
-
Set an expiration date (recommended: 90 days or custom)
-
Select the following scopes:
repo(Full control of private repositories)- This includes
repo:status,repo_deployment,public_repo,repo:invite, andsecurity_events
- This includes
- Alternatively, if analyzing only public repositories, you can use just:
public_repo(Access public repositories)
-
Click "Generate token"
-
Copy the token immediately - you won't be able to see it again!
- For private repositories:
reposcope - For public repositories only:
public_reposcope
The script needs read access to pull requests, reviews, and timeline events.
The ./run script runs the analysis in a Docker container, so you don't need Ruby installed locally.
GITHUB_TOKEN=your_token_here ./run owner/repoGITHUB_TOKEN=your_token_here ./run owner/repo YYYY-MM-DD
GITHUB_TOKEN=your_token_here ./run owner/repo YYYY-MM-DD YYYY-MM-DD- Repository (required): GitHub repository in
owner/nameformat (e.g.,facebook/react) - SINCE date (optional): Start date for analysis in
YYYY-MM-DDformat (defaults to2008-01-01) - UNTIL date (optional): End date for analysis in
YYYY-MM-DDformat (defaults to current time)
The script analyzes PRs that were merged between the SINCE and UNTIL dates.
You can set the GITHUB_TOKEN environment variable in several ways:
Option 1: Inline (recommended for one-time use)
GITHUB_TOKEN=ghp_xxxxxxxxxxxx ./run owner/repo 2025-08-01Option 2: Export in your shell session
export GITHUB_TOKEN=ghp_xxxxxxxxxxxx
./run owner/repo 2025-08-01Option 3: In your shell profile (for repeated use)
Add to ~/.bashrc, ~/.zshrc, or equivalent:
export GITHUB_TOKEN=ghp_xxxxxxxxxxxxThen reload your shell or run source ~/.bashrc
.env file (and add it to .gitignore) or a secrets manager.
Analyze all merged PRs (from 2008-01-01 until now):
GITHUB_TOKEN=ghp_xxxxxxxxxxxx ./run myorg/myrepoAnalyze PRs merged from August 1st until now:
GITHUB_TOKEN=ghp_xxxxxxxxxxxx ./run myorg/myrepo 2025-08-01Analyze PRs merged in November 2025:
GITHUB_TOKEN=ghp_xxxxxxxxxxxx ./run myorg/myrepo 2025-11-01 2025-11-30Running without Docker (if you have Ruby installed):
GITHUB_TOKEN=ghp_xxxxxxxxxxxx ruby lib/prcrastinate.rb myorg/myrepo
GITHUB_TOKEN=ghp_xxxxxxxxxxxx ruby lib/prcrastinate.rb myorg/myrepo 2025-08-01The script generates two CSV files:
One row per PR with columns:
repo: Repository namepr_number: PR numberpr_url: Link to the PRpr_title: PR titlepr_author: GitHub username of PR authorcreated_at: When the PR was createdmerged_at: When the PR was mergedis_draft: Whether the PR was a draftfirst_review_at: When the first review was submittedcreated_to_first_review_seconds: Latency from creation to first reviewearliest_review_requested_at: When the first review was requestedreview_requested_to_first_review_seconds: Latency from review request to first reviewlast_commit_before_first_review_at: Last commit before the first reviewlast_commit_to_first_review_seconds: Latency from last commit to first review
One row per re-review cycle (after CHANGES_REQUESTED) with columns:
repo: Repository namepr_number: PR numberpr_url: Link to the PRcycle_index: Which re-review cycle this is (1, 2, 3...)cycle_start_at: When the cycle started (first commit after changes requested)cycle_end_at: When the cycle ended (next review submission)cycle_seconds: Duration of the re-review cyclecycle_trigger: What triggered the cycle (e.g.,AUTHOR_COMMIT_AFTER_CR)end_review_state: State of the review that ended the cycleend_reviewer: Who submitted the review that ended the cycle
The CSV files can be imported into Excel, Google Sheets, or any data analysis tool.
Suggested analyses:
- Create pivot tables grouping by week or month
- Calculate mean, median, and p90 (90th percentile) review latencies
- Filter out draft periods or bot activity
- Identify trends over time
- Compare latencies across different time periods
"Missing GITHUB_TOKEN env var"
- Make sure you've set the
GITHUB_TOKENenvironment variable
"HTTP error 401" or "Bad credentials"
- Your token is invalid or expired - generate a new one
"HTTP error 403" or "Resource not accessible"
- Your token doesn't have the required scopes
- For private repos, ensure the
reposcope is enabled - The repository might not exist or you don't have access
"GraphQL errors"
- Check that the repository name is in the correct format:
owner/name - Verify the dates are in
YYYY-MM-DDformat
