Your Pull Request Is Too Big. Here Is How to Tell.
by Eric Hanson, Backend Developer at Clean Systems Consulting
The Size Problem Nobody Wants to Name
Your PR has been open for four days. The reviewer left two comments on day one and hasn't been back. You send a gentle ping and get "I'll get to it." The PR is 1,800 lines of diff across twenty-two files.
Here's what's happening: the reviewer opened the PR, saw the scope, and did the math. Reviewing 1,800 lines properly would take two to three hours of uninterrupted focus. They don't have two hours. They're waiting for a window that isn't coming, so the PR sits.
This is not a reviewer motivation problem. It's a PR size problem.
The Signal Thresholds
The research that exists on code review quality is not extensive, but what's there is consistent. Cisco's study on peer code review (published in their Best Kept Secrets of Peer Code Review report) found that reviewers who looked at more than 400 lines in a session showed significantly lower defect detection rates. SmartBear's data from the same era found similar patterns.
Beyond the research, the practical thresholds that experienced teams converge on:
- Under 200 lines — reviewed in one sitting, gets thorough attention, quick turnaround
- 200–400 lines — still reviewable, good reviewers will read it carefully, may take a day
- 400–800 lines — reviewers will focus on high-level structure and obvious errors; detail-level bugs get through
- Over 800 lines — expect checkbox reviews, courtesy approvals, and deferred concerns
These aren't hard cutoffs. A 600-line PR that's all test additions is easier to review than a 300-line PR that restructures the authentication flow. But the heuristic holds: size is a strong predictor of review quality.
How to Tell If Your PR Is Too Big
The quick diagnostic:
# Lines added and removed
git diff --stat origin/main...HEAD | tail -1
# Files changed
git diff --name-only origin/main...HEAD | wc -l
# A quick summary
git diff --shortstat origin/main...HEAD
If the output shows more than 500 changed lines or more than 10 files, it's worth asking whether it can be split.
Beyond the numbers, the content signals:
The PR description requires "and" to explain what it does. "Adds payment retry logic and refactors the notification service and updates the database schema." That's three PRs.
You can't summarize the PR in one sentence. If explaining it requires a paragraph, the scope is probably too broad.
The PR touches unrelated systems. Payment code changes and logging infrastructure changes in the same PR means the review requires expertise in two different areas simultaneously.
The commit history has commits that could stand alone. If you run git log --oneline origin/main..HEAD and see commits that obviously address separate concerns, those are your natural split points.
How to Split a Large PR
The most common split patterns:
Separate refactoring from behavior change. Rename variables, extract methods, reorganize files — commit that without any behavior change. Then add the feature on top. The refactor PR is easy to review (behavior doesn't change, so the reviewer just checks that the refactor is clean). The feature PR is smaller and easier to review in isolation.
Layer the implementation. Data model first. Service layer second. API endpoints third. Tests and documentation fourth. Each layer is independently reviewable even if they're submitted as sequential PRs in a stack.
PR #1: Add idempotency_keys table migration
PR #2: Add IdempotencyKeyService with storage and lookup
PR #3: Wire IdempotencyKeyService into payment endpoint
PR #4: Add integration tests for full retry flow
Separate the infrastructure from the feature. Adding a feature flag system and adding the first feature behind a flag are two PRs, not one.
Extract unrelated changes. If you touched a typo, a config cleanup, or an unrelated bug fix during your feature work, commit those separately and submit them as their own tiny PRs. They'll merge immediately with zero overhead.
The Argument Against Splitting
The most common pushback: "Splitting PRs creates dependencies. If PR #1 isn't merged, PR #2 can't be reviewed meaningfully."
This is partially true, but the alternative is worse. A 1,500-line PR reviewed cursorily produces more bugs than four 400-line PRs reviewed properly — even accounting for the coordination overhead of sequencing.
The practical mitigation: use stacked branches so you can work on PR #2 before PR #1 merges. Most modern Git forges (GitHub, GitLab) show diffs relative to the base branch of a stacked PR, so reviewers see only the delta, not the full accumulated diff.
# Stack your branches
git checkout -b feature/idempotency-schema
# work and push PR #1
git checkout -b feature/idempotency-service
# work on top of idempotency-schema, push PR #2 targeting idempotency-schema
The Team Norm Worth Establishing
Set a soft limit — 400 lines of diff — that triggers a "should this be split?" conversation before review is requested. Not a hard block; a prompt. Put it in your PR template:
> **Size check:** If your diff is over 400 lines, describe why it can't be split,
> or link to the split plan.
Most developers, when prompted to think about it, can find a reasonable split. The prompt is all that's needed — the instinct to batch work is strong, but it's not irreversible.