Read Anthropic’s case study about Graphite Reviewer
Background gradient

Most modern software development  workflows rely heavily on pull requests—a mechanism for proposing, discussing, and reviewing code changes before they are merged into the main codebase.

While pull requests encourage teamwork, doing them well requires thoughtfulness and care. If developers rush to ship new features, it can become easy to cut corners on pull requests—leading to piles of tech debt that eventually halt or slow down the development process.

It's simple: teams that handle pull requests well, ship new features faster, and have happier engineers. Handling PRs poorly has the exact opposite effect. 

Let’s understand some pull request best practices you can introduce to your team and how they can benefit authors, code reviewers, and the overall workflow.

Before jumping into the pull request best practices, let’s understand why traditional PR practices fail.

Even with good intentions, traditional pull request workflows often fall short in a few key areas:

Feature creep: Pull requests become overloaded with multiple changes, spanning different contexts, making it difficult to understand the scope and review each change effectively. 

For example, let's say a developer bundles a new recommendation algorithm, visual redesigns of the home page, and a migration to a microservices architecture into one massive PR spanning over hundreds of files. Because the change is so large, reviewers then struggle to test and validate each component which  delays the merge, and prevents the author from continuing development.

“Feature creep is an innocent process. An engineer looking at a prototype of a remote control might think to herself, “Hey, there’s some extra real estate here on the face of the control. And there’s some extra capacity on the chip. Rather than let it go to waste, what if we give people the ability to toggle between the Julian and Gregorian calendars?” — Chip Heath & Dan Heath, Made to Stick: Why Some Ideas Survive and Others Die

Unintentional dependencies: Changes can inadvertently introduce dependencies on future features or seemingly unrelated functionalities, creating tangled code and hindering future development. This "domino effect" can significantly slow progress and increase maintenance complexity as discrete aspects of the codebase become interlinked.

Let’s return to our recommendation algo. Let’s say the PR also included some database query optimizations, which inadvertently caused the product search feature to slow down. The underlying indexes were adjusted, creating widespread slowdowns—these dependencies were not intended when the code was being written.

Knowledge silos: Code reviews should not neglect other considerations like performance, UX, and broader architectural implications. A pitfall of a bad code review process is when reviewers focus too narrowly on code quality and functionality, and neglect to consider the broader impact of the changes being proposed—likely due to a lack of knowledge in the domain.

For example, the PR described above included caching to improve performance. However, the reviewers did not consider how this might impact overall infrastructure costs and complexity. As a result, the code was approved, but it ended up having a negative impact on the system as a whole.

Good code reviews take a holistic approach, and consider all of the potential implications of the changes being proposed.

Context vacuum: Another pitfall is that pull request descriptions and commit messages often lack sufficient context, leaving reviewers guessing about the purpose and motivation behind the changes. 

For instance, to fix the above caching issue, a developer creates another PR titled "Fix bug" that modifies a core module without explaining the adjustments. However, the commit message is not descriptive enough for a reviewer to know what changes have been made—there is no context for the bug fix. 

The reviewer is then forced to either directly ask the author for more context, or go digging through the codebase themselves, searching for the reason behind the proposed changes. 

Big ideas developed in a vacuum are doomed from the start. Feedback is an essential tool for building and growing a successful company. — Jay Samit, Independent Vice Chairman, Deloitte Digital

Review bottlenecks: Large pull requests can lead to review fatigue, causing lengthy delays and impacting team productivity. Additionally, relying on a small pool of reviewers creates bottlenecks and hinders knowledge sharing within the larger team. 

For example, the recommendation algo PR may wait for weeks for the only person familiar with the parameters and weights of the algorithm. This dependency can make it difficult to get features rolled out faster, as the author is blocked on the review to merge the code and continue development.

These common pitfalls highlight the need for more conscious and proactive efforts to get the most out of your pull request process.

Efficiency in code reviews isn't the only goal—teams must invest in nurturing collaboration and knowledge sharing. Let's explore some key practices engineering leaders can implement within their teams to speed up their PR workflows and minimize friction.

One of the most impactful pull request best practices is to keep them small and tightly scoped, with changes of less than 200 lines on a single PR, the ideal PR being <50 lines of code

On average, we’ve found that teams with PR sizes hovering around the 50-line average, ship 40% more code than a similar team doing 200+ line PRs. Smaller PRs also make it easier to write proper unit tests for each module, and make reverting regressions much easier.

"If somebody sends you a code review that is so large you’re not sure when you will be able to have time to review it, your typical response should be to ask the developer to split the CL into several smaller CLs that build on each other." — Speed of Code Reviews

Keeping PRs concise encourages reviewers to assess code changes quickly rather than become overwhelmed. It also promotes authoring commit messages that summarize modifications at an appropriately granular level, something that becomes harder when you’re trying to capture more context.

However, tight scoping can be challenging to implement when a team is used to a particular PR workflow. That’s where techniques like PR stacking can help.

Stacked PRs partition big changes into a logical sequence of small, iterative modifications that build on top of each other. Initial PRs establish core infrastructure, while subsequent ones build on those changes. Stacks enforce the separation of features into smaller parts while allowing workstreams to progress in parallel without blocking.

The idea behind stacked diffs is that you can keep working on your main branch, and worry about reviews later. You check out the main branch and start working on it, make a small change, and commit this as a diff – a very small pull request. You then continue working, creating a second diff, a third, and so on. — Gergely Orosz, The Pragmatic Engineer

Returning to the recommendation algorithm example, a developer designing the algorithm can break it into three parts—the algorithm itself, the database queries, and the front-end interactions. This can help you get reviews faster, and merge into main more quickly. 

While stacking is possible with GitHub, specialized tools like Graphite and ghstack help manage dependencies across feature branches. They automate rebasing and synchronizing cascading changes between linked, stacked PRs—leaving your team free to work on the real challenges instead of getting bogged down by git operations.

Additionally, PR authors should provide ample contextual details to help reviewers evaluate the changes more easily. Make it a team-wide practice that the descriptions should clearly state the motivation behind changes, with links to related domain logic and prior discussions around alternatives or constraints.

For user-facing changes, embed before/after screenshots to clearly show the user interface (UI) and behavioral deltas. Outline edge cases validated through unit testing across various environments, browsers, and datasets.

Finally, explicitly call out any breaking changes, downstream integration impacts, or compatibility considerations that reviewers should specifically analyze so potentially risky modifications get the scrutiny they deserve.

When it comes to software architecture, it's important to implement some safeguards that prevent quality from slowly worsening over many incremental changes. 

  • Focus on building modular components that make testing and releasing code faster and easier.

  • Abstraction is key —you want to break out functionality into modular chunks to reduce complexity, making the code more extensible and easier to maintain. Another aspect is handling updates thoughtfully—maintain compatibility with previous versions unless you have precisely coordinated timelines to sunset legacy systems. 

  • It also helps to designate reviewers based on responsibility of impacted components since they will best understand the potential downstream impacts with a big-picture view.

While working on features and fixes, try to encourage developers to actively seek feedback and engage others in the moment instead of waiting for PR reviews. 

Find opportunities for rapid prototyping, pair programming, informal reviews, and live discussions that help promote the flow of ideas and contextual collaboration rather than blocking developers.

The idea is to create a supportive environment where asking questions is viewed as a sign of responsible development and gradually reinforce the behavior by rewarding it publicly. You also need to work towards making the feedback loop frictionless so it becomes second-nature to developers. 

At the end of the day, we want to create an environment where developers not only feel supported and appreciated, but also productive—with as few things blocking their workflows as possible.

An often underestimated aspect is identifying the right reviewers for each PR based on the specific types of analysis required. 

Don't haphazardly assign reviewers. Instead, thoughtfully tap both technical and non-technical experts that can best validate modifications.

  • For core infrastructure changes, loop in senior engineers who handle platform reliability to assess operational impacts. 

  • For UI updates, include UX designers to represent end-user needs. 

  • Treat security reviews as integral for changes touching encryption, access controls, and exposure boundaries.

The reviews become more efficient and accurate since the reviewers can focus on what they do best instead of context-switching. Small PRs also help here, as you can pinpoint concerns, making it easier to granularly assign reviewers based on their domain expertise.

Scaling code review requires balancing team bandwidth against incoming PR volume to avoid hitting unmanageable queues. 

Begin by setting expectations around PR turnaround times based on team capacity, limiting work-in-progress pull requests. 

 Measuring metrics like “time to first review” and “time from publish to merge” can help identify shortcomings in your pull request workflows.

"If you are not in the middle of a focused task, you should do a code review shortly after it comes in. One business day is the maximum time it should take to respond to a code review request (i.e., first thing the next morning)." — Speed of Code Reviews, Google

When making any changes to existing process, remember to gather feedback from engineers and other stakeholders to understand their perspective.

Upon publishing a PR, make sure changes are run through some form of automated code review and linting. You can leverage tools like GitHub Actions and Jenkins (using SonarQube or Checkstyle) to catch syntax errors, enforce style guides, and discover security vulnerabilities. 

This will:

  • Free up human reviewer time to focus on business logic assessments.

  • Enforce style and quality standards across the entire codebase.

  • Surface more subtle or convoluted issues humans may miss.

Adding automated reviews as a required PR step will filter out many basic defects like minor styling, complexity, and vulnerability issues before a human review occurs. Allow automation to handle the frequent shallow issues so humans can focus their effort assessing deeper logic and UX.

Apart from code review, identify opportunities anywhere in the development lifecycle that can be automated—from code analysis to testing and release management. 

The main goal is increasing developer productivity, not just mechanically enforcing rigid rules. 

When done right, efficient pull requests resolve workflow bottlenecks and actively accelerate team momentum long-term. That happens by framing changes, helping reviewers understand differences, and inviting expert input across disciplines. 

Reviews begin to feel less like approvals and more like helpful conversations giving developers the confidence to build faster and gain contextual knowledge. However, lasting velocity gains come from actively refining systems over time. 

  • Track key metrics to guide experiments with new workflows.

  • Automate repetitive tasks to conserve focus for high-priority tasks.

  • Open up the dialogue with your team members to discuss best practices and gather feedback on incremental workflow changes.

The real win materializes when a culture of humble self-betterment takes root organically. Pull requests become collaboration points and help take your team to peak development and excellence—but only for teams that invest heartfelt energy into implementing and continually improving the workflows.

Optimizing pull request practices isn't a one-time initiative but an ongoing commitment. To sustain collaboration velocity, teams must actively strengthen the ecosystem through metrics-driven experimentation, knowledge sharing, and intelligent automation.

Monitor key metrics like review turnaround time, bugs caught, and time-to-merge. Then, start scheduling regular retrospectives to discuss insights, trends, and areas needing fine-tuning.

Try variations around review cadence, PR communication modes, and tooling integrations to determine what clicks best. Also, survey developers regularly to hear what's working and what is frustrating. Start small with any new workflows, make your team get a hang of it, and then start rolling out widely. 

Make time for developers to review each other's code informally. This will also help spread skills and get feedback before the code is sent for review. Run training workshops to teach best practices for writing and assessing pull requests. When you see proactive collaboration among team members, celebrate it publicly.

Pull requests offer a unique opportunity—a chance to build connections, encourage growth, and compound team talents into collective achievements greater than any individual contribution. 

The teams that actively optimize pull requests automatically set in motion a flywheel effect, pushing the products and the team members to new heights. 

However, realizing the potential for new PR workflows needs intention and care.

The deciding factor is whether teams can invest the time and effort in streamlining the technical and cultural infrastructure needed for friction-free collaboration. 

That’s where tools like Graphite come into the picture. 

They provide the missing layer—automation of operational drudgery—allowing your senior developers to focus on high-value assessments. Graphite’s built-in integrations also streamline cross-linking stacked pull requests while advanced analytics offer visibility into bottlenecks—helping you improve workflows through data-backed decisions. 

Try Graphite today and experience how these pull request practices can supercharge your team’s productivity with minimal effort.

Built for the world's fastest engineering teams, now available for everyone