Skip to content
← All insights
Developer workflow10 min read

Smaller pull requests: faster feedback without hiding the real change

Why smaller pull requests are easier to review, test and release, how to split work without losing the thread of a feature, and when a larger coordinated change is the safer choice.

A pull request is a unit of review, not a diary of the work

A pull request should give another engineer a fair chance to understand what changed, why it changed and what evidence supports it. When one request contains several unrelated decisions, that job becomes much harder.

Small does not mean counting lines without context. A ten-line change to authorisation can carry more risk than a two-hundred-line new screen. The practical aim is a coherent change with a clear purpose, limited surface area and evidence that matches the risk.

Treat experiments, false starts and unrelated cleanup as part of the working process, not necessarily part of the review. The finished pull request should tell a readable story about the change that is ready to merge.

Smaller changes improve review quality

Reviewers have limited attention. A focused diff makes it easier to trace data flow, question an assumption, compare a test with the behaviour and notice an accidental change. A large diff encourages broad approval because nobody can hold every detail in mind.

Fast review also reduces merge pain. While a branch waits, the surrounding code changes and the author loses context. A smaller request can be reviewed, amended and merged before conflicts and follow-up questions accumulate.

This is not an argument for shallow review. It gives a reviewer more capacity to examine the part that matters. The request should still explain the decision, name known limitations and include the right level of test and operational evidence.

Small pull requests make release and rollback safer

A focused change narrows the likely cause when a deployment behaves unexpectedly. It is easier to revert one feature flag, validation rule or query change than a mixed batch of refactoring, dependency movement and new behaviour.

Smaller increments also support progressive delivery. A team can add a database field, deploy code that tolerates its absence, backfill data and then enable a new path. Each step is independently safe, which reduces the pressure for one large release window.

The benefit is not zero risk. A sequence of individually reasonable changes can still create an unsafe outcome if the dependency order is unclear. Document the rollout and rollback path when steps need to land in a particular order.

Split a schema change into deployable stepstext
1. Add a nullable database column.
2. Deploy code that reads old and new representations.
3. Backfill existing records.
4. Start writing the new value.
5. Make the new value required after evidence confirms the migration.

Each step can be reviewed and released independently.

Split by decision and dependency, not arbitrary file count

A useful split keeps closely related behaviour together. A new endpoint, its request validation, service rule and focused tests may belong in one request because separating them would make neither change meaningful on its own.

Look for decisions that can stand alone: introduce an interface before changing an adapter, add observability before a risky migration, make a mechanical rename separately from a behaviour change, or add a feature flag before enabling a new route.

Avoid splitting a change so finely that reviewers must open five requests to understand one simple outcome. A good sequence lets each request build on the last while remaining safe and intelligible in isolation.

Use feature flags and compatibility to keep work moving

A feature flag can separate deployment from exposure. The code can be merged and exercised in a limited context before users receive the new behaviour. This makes it possible to integrate work in smaller slices without keeping a long-lived branch open.

Flags need ownership and removal dates. A permanent collection of flags creates paths that tests and future engineers must reason about. Record who will remove a flag, what evidence enables it and which rollback action remains available.

Backward-compatible contracts are equally useful. Tolerant readers, additive response fields and staged database changes let independently deployed services move without a precisely timed merge or release.

Recognise the trade-offs and exceptions

More pull requests mean more descriptions, reviews and merge events. If the work is already very small, splitting it further can add ceremony without improving understanding. The right threshold depends on the team, codebase and change risk.

Some changes need coordination. A security fix may need to land as one controlled patch. A generated API client and the server contract it represents may need to change together. A difficult refactor can require a larger request when temporary intermediate states would be misleading or unsafe.

When a larger request is necessary, compensate with structure: separate commits by concern, provide a walkthrough, call out the high-risk files, explain what cannot be split and give reviewers enough time and evidence to assess it.

Make the smaller path the easy path

Teams get smaller pull requests when their workflow supports them: frequent integration, reliable focused tests, quick review expectations, feature flags and a shared understanding that a work-in-progress request can invite early discussion.

Do not turn size into a performance metric. Engineers may then omit tests, hide changes in follow-up requests or create artificial fragments simply to satisfy a number. Review clarity, lead time, defect rate and deployment confidence are better signals of whether the habit is helping.

Aim for a pull request that a reviewer can understand in one sitting and that the team can release with confidence. When that is not possible, explain why and make the larger change as navigable as you can.

  • Give every pull request one clear purpose
  • Separate mechanical cleanup from behavioural change where practical
  • Split database and contract changes into compatible deployment steps
  • Use feature flags with an owner and removal plan
  • Keep dependent behaviour together when splitting would obscure the outcome
  • Use commits and a written walkthrough to structure unavoidable large requests
  • Judge the practice by review quality and delivery confidence, not a line-count target