Batch low risk upgrades that share an ecosystem and have strong tests, and ship risky ones alone. A batch cuts review and CI overhead, but when it breaks you must find which change did it. If you cannot bisect cheaply, make the batch smaller. Security fixes for exposed code should not wait for a batch.
The trade off
| Approach | Strength | Weakness |
|---|---|---|
| One upgrade per pull request | A failure points to one cause. Easy rollback | Many pull requests, repeated CI runs, review fatigue |
| Large batch | Few reviews, one CI run | A failure has many suspects. Rollback undoes good changes too |
| Grouped by risk | Balances both | Needs a rule and some tooling |
GitHub's Dependabot configuration documents a groups option that bundles updates into one pull request, so grouping is a supported workflow rather than a hack.
A grouping rule that works
Group by risk and by type, not by convenience.
- Patch and minor updates of development tools go together, weekly. Low blast radius.
- Patch updates of runtime libraries with good test coverage can go together.
- Packages on a trust boundary, such as authentication, cryptography, parsers, database drivers and HTTP clients, ship alone or in pairs.
- Major versions always ship alone. See testing a major upgrade in small steps.
- Security fixes ship as soon as they are verified, outside the schedule.
Keep one ecosystem per batch. A Python batch and a JavaScript batch fail for different reasons and roll back differently.
When a batch breaks: bisect it
Git has a bisect command that uses binary search to find the commit that introduced a bug, and it can run a script on each step to automate the search. For a batch, the same idea works on the list of upgrades.
- Confirm the batch fails and the previous state passes.
- Apply half of the upgrades. Run the failing test or smoke test.
- If it fails, the culprit is in that half. If it passes, it is in the other half.
- Repeat until one upgrade remains. A batch of sixteen needs about four rounds.
- Ship the batch without the culprit, and handle the culprit on its own.
This is cheap only if your tests run quickly and you can apply upgrades individually. If your lockfile cannot be partially updated, or the failing test takes an hour, the batch was too big.
Make small batches practical
- Keep CI under ten minutes for the smoke path.
- Use a bot that can group updates and also split one out on request.
- Commit lockfile changes separately from code changes, so you can revert cleanly.
- Write the batch rule in the repository so every maintainer follows it.
For a volume view on bot pull requests, see auto triage rules for Dependabot pull requests at scale.
Watch for the lockfile effect
Batching also changes transitive packages. Read the combined lockfile diff, not just the list of direct bumps. See testing a transitive bump.
Safeguard's fix pull requests are off by default with every category on Manual, so teams choose their own grouping and review rules, and its policies and gates apply to each pull request the same way. Free scan: gold.safeguard.sh/scan.
Quick check
Is a weekly batch of all updates a bad idea?
Not if the risk is low and tests are good. Split out trust boundary packages and major versions so a failure has few suspects.
How do I find which upgrade in a batch broke the build?
Bisect: apply half the upgrades, test, and narrow down until one remains. Git bisect automates this for commits.
Sources
Last reviewed: 19 October 2026.