Why Your Pull Requests Are Stuck
Pull requests can take a long time to complete due to number of factors, including the size of the changes, the complexity of the code and the availability if reviewers.
Limit the size of your pull requests
Big pull requests can slow down code reviews. When you start with a few small changes, it's easy to add in larger, complex updates, making the review process harder.
I often see pull requests that mix in new features, code fixes, and bug fixes, which could have been split into smaller, easier-to-review requests. Teams that value good code reviews prefer these smaller pull requests. While it might take a bit more time upfront, it ultimately helps the team be more productive and keeps everyone less stressed.
However, don’t overdo it. Breaking changes into too many tiny pieces can make things confusing. There’s no exact limit for the ideal number of lines in a pull request. Just think about how many lines you’re changing and how complex those changes are for the reviewer.
For new projects, big pull requests are common because getting features out quickly is the priority. However, this can lead to more bugs later when you have paying customers, costing your team more time and effort to fix these issues after release than if they had been caught during a thorough review with smaller requests.
10 reasons why pull requests are slow
1. PRs Are Too Big
- Large pull requests (PRs) with lots of code are hard for reviewers to handle.
- Example: A PR that changes the entire authentication system and updates the UI all at once.
- Why It Matters: Big PRs can overwhelm reviewers, leading to slow reviews and more chances for bugs to be missed.
2. Larger PRs Bring More Risks
- Bigger PRs are trickier to test and can cause unexpected problems.
- Example: A large PR for payment processing accidentally breaks user profile management, locking users out.
- Impact: This increases the chance of bugs affecting parts of the app that aren’t related to the PR.
3. Long PRs Slow Down the Team
- PRs that take a long time to approve can become outdated.
- As the codebase changes quickly, it can lead to conflicts and extra work.
- Impact: Developers waste time fixing conflicts, which slows the whole team's progress and can disrupt project timelines.
4. Limited Reviewer Availability
- Reviewers may be busy with other work and unavailable.
- Example: Senior developers have too many tasks to review PRs promptly.
- Why It Matters: With few available reviewers, it takes longer to get PRs approved, creating delays.
5. Low Priority on Code Reviews
- Code reviews often get pushed aside for new developments.
- Example: Developers focus on adding new features instead of reviewing code.
- Impact: This slows down development and reduces the benefits of having peer reviews.
6. Poor Company Culture and Communication
- A lack of teamwork and communication can hinder the review process.
- Example: Developers work alone and don’t feel rushed to review others' PRs.
- Why It Matters: Without good communication, PRs can be ignored for too long.
7. Time Zone Issues in Global Teams
- Teams around the world may face delays because of different time zones.
- Example: A European developer submits a PR late in their day, but the US reviewer sees it the next day.
- Impact: Extra delays can occur, especially if multiple review rounds are needed.
8. Complicated Review Processes
- Complex review systems or tools can slow down PR approvals.
- Example: New team members struggle to learn a difficult code review tool.
- Why It Matters: Complicated tools make it hard to be efficient; simpler tools help reviews go faster.
9. Unclear Code Ownership
- If it’s not clear who should review a PR, it might be forgotten.
- Example: A PR is submitted without assigned reviewers; others think someone else will take care of it.
- Impact: PRs can sit unreviewed for too long, delaying fixes and new features.
10. Fear of Conflict
- Developers may avoid giving honest feedback to prevent hurt feelings.
- Example: A reviewer sees a big problem but doesn’t mention it to avoid upsetting the author.
- Why It Matters: This hesitation slows down reviews and lowers code quality. Knowing how to give feedback effectively can help.
How to Spot the Trend:
To see how long it takes for changes to go from code to deployment, you can measure something called Lead Time for Changes. This is an important DevOps metric. You can break the whole process into stages:
- Coding Time: From when the code is committed to when the pull request (PR) is opened.
- Pickup Time: From when the PR is opened to the first review.
- Review Time: From the first review until the PR is merged.
- Deployment Time: From when it’s merged until it’s live in production.
By looking at these stages, you can find out where things are slowing down. For example, if review time is getting longer, it might mean that there are too many PRs getting opened without being looked at, or the PRs are too big, making them hard to review.
Solutions:
Here are some ways to fix the slowdowns:
- Make PR Reviews a Priority: After daily meetings, focus on merging PRs before starting new tasks.
- Reduce Work in Progress (WIP): Limit the number of active tasks to avoid delays caused by waiting for others.
- Encourage Smaller PRs: Smaller PRs are easier and quicker to review. Aim for one change per PR.
Managing Pull Requests in a Team
1. Understand the Pull Request Workflow
A pull request is a request to merge code changes from one branch into another (usually the primary branch, e.g., main
or develop
). This process involves:
- Code Writing: A developer makes changes on a feature branch.
- Pull Request Creation: The developer opens a pull request (PR) for review.
- Code Review: Team members review the code for errors, adherence to standards, and quality.
- Testing: Automated or manual tests are run.
- Merging: Once approved and tested, the PR is merged into the target branch.
2. Set a Standardized Branching Strategy
A clear branching strategy allows everyone to know which branch serves what purpose. A popular example is Git Flow, which includes:
main
: Production branch.develop
: Pre-production/integration branch.- Feature branches (
feature/xyz
): Individual work for a specific feature or bugfix. - Hotfix branches (
hotfix/xyz
): Quick fixes to patches.
# Example Git Flow Workflow
git checkout -b feature/add-login-button # Create a new feature branch
<make some changes>
git add . && git commit -m "Add login button"
git push origin feature/add-login-button # Push the feature branch to remote
3. Establish Clear PR Guidelines
Encourage team members to adhere to clearly defined pull request rules:
- Use descriptive titles and summaries for the PR.
- Link relevant tickets/issues (e.g., Jira, GitHub issues).
- Break PRs into smaller, reviewable chunks.
- Follow a coding style guide.
# Example Pull Request Template (GitHub)
## Summary
- What does this PR do?
## Linked Issue
- Fixes #123 (Add login functionality)
## Review Checklist
- [ ] Code is readable and follows standards
- [ ] Tests have been written/updated
- [ ] New functionality was tested manually
4. Implement Code Reviews
Code reviews are a key step in ensuring code quality. Review involves:
- Automated Checks: Use CI/CD pipelines to execute jobs (e.g., running tests, linting code, checking security).
- Peer Reviews: Assign team members to review the PR for readability, logic, and completeness.
# Adding a reviewer on GitHub (command-line using hub)
hub pull-request -a @reviewer_username
Best Practices for Reviewers
- Provide constructive feedback.
- Focus on logic, maintainability, and scalability.
- Use inline comments sparingly and explain suggested changes.
// Inline comment example during code review (GitHub or GitLab)
function add(a, b) {
return a + b;
}
// Suggestion: Use a type-checking library like lodash to verify inputs are numbers.
5. Automate with CI/CD
Automating with Continuous Integration (CI) tools ensures PRs meet standards before being merged. Examples include:
- Linting Code: Verify formatting and syntax.
- Unit Tests: Run predefined test cases.
- Build Verification: Ensure code builds successfully.
Example with GitHub Actions:
# .github/workflows/ci.yml
name: Pull Request CI
on: [pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '16'
- name: Install dependencies
run: npm install
- name: Run tests
run: npm test
- name: Lint code
run: npm run lint
6. Use Merge Strategies
Define how pull requests are merged into the main branch. Common strategies include:
- Rebase and Merge: Keeps a linear commit history.
- Squash and Merge: Consolidates all commits into a single commit.
- Merge Commit: Creates a merge commit without squashing commits for detailed history.
Example GitHub Settings:
Options:
- Enable "Rebase and Merge" for feature branches.
- Require at least one approved review before merging.
- Enable "Require status checks to pass before merging."
7. Track and Communicate Review Progress
Tools like GitHub, GitLab, or Bitbucket can notify team members of pending reviews. Encourage teams to prioritize PR reviews in their workflow. Possible methods:
- Set Service-Level Objectives (SLOs) for PR reviews (e.g., review within one business day).
- Use Slack/GitHub integrations to alert reviewers.
// Example Slack Notification (using GitHub Actions)
on: pull_request
jobs:
notify:
steps:
- name: Send Slack Notification
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
author_name: 'GitHub Bot'
8. Track Metrics for PR Management
Monitor the following metrics to improve the process:
- Time-to-Review: Average time it takes to review.
- PR Size: Keep PRs small and manageable.
- Merge Frequency: How often changes are merged.
- Defects in Merged PRs: Track post-merge issues.
Code Example: Full PR Management Workflow
Imagine adding functionality to fetch user data from an API:
# Step 1: Create a feature branch
git checkout -b feature/fetch-user-data
# Step 2: Make changes
# (in file user.js)
export async function fetchUserData() {
const response = await fetch('/api/users');
return await response.json();
}
# Add and commit changes
git add user.js
git commit -m "Added fetchUserData function"
# Step 3: Push to remote
git push origin feature/fetch-user-data
# Step 4: Create the PR (on GitHub or CLI)
hub pull-request -m "Added fetchUserData function for user API"
# Step 5: CI/CD pipeline runs tests automatically (e.g., Jest)
npm test
# Outputs: PASS user.test.js
The reviewer checks the logic, approves the PR, and merges it using a squash and merge strategy.
Summary of the 10 Tips
- Break Down PRs Into Manageable Sizes.
- Use Pull Request Templates for Standardization.
- Automate Code Quality Checks.
- Assign Responsible Reviewers.
- Review PRs Daily to Avoid Bottlenecks.
- Set Time Limits for Reviews.
- Add Context and Test Instructions in PRs.
- Choose Consistent Merge Strategies.
- Track Metrics to Improve the Workflow.
- Provide Constructive Feedback on Reviews.
I made a free project management tracker dashboard in Notion. Check it out if you're interested. Download