Multiply it out. Every install uses several connections, every runner runs one or more installs, and a matrix build starts many runners at once. Cap concurrency at the pipeline level, stagger scheduled jobs, and put a cache between runners and the registry so the peak stays inside what your mirror and upstream can take.
Do the arithmetic once
npm's documentation lists maxsockets as the maximum number of connections per origin, with a default of 15. That is a setting for one process. It is not a fleet limit, and it shows how quickly the numbers grow.
An illustration, with made up numbers: 100 jobs start together after a merge, and each installs with up to 15 connections to the registry. Worst case, that is up to 1,500 simultaneous connections to one origin from your fleet. Real installs rarely hit the ceiling for the whole run, but the peaks line up because the jobs start at the same moment.
Use your own numbers. Count jobs per minute at your busiest time, not the average.
Why it hurts
- The public registry may rate limit your egress address. See why CI jobs hit pull rate limits.
- Your own mirror may slow down or fail under the burst, and then every job retries.
- Retries multiply the problem, as described in retry storms.
- Slow installs make jobs time out, which triggers more reruns.
Controls, from cheapest to most work
| Control | What it does | Notes |
|---|---|---|
| Pipeline concurrency limits | Caps how many jobs of a kind run at once | Use your CI system's concurrency or queue settings |
| Stagger scheduled jobs | Spreads nightly work over a window | Add random offsets, not one shared minute |
| Shared cache | Turns repeated downloads into local reads | See warm CI caches |
| Mirror or pull-through cache | One upstream fetch serves many jobs | See pull-through cache proxy settings |
| Lower tool concurrency | Reduces connections per install | Change defaults only after measuring |
| Backoff with jitter | Keeps retries from lining up | Honour Retry-After when sent |
A practical rollout
- Measure the peak. Find the busiest five minutes in the past month and count installs.
- Check what the mirror served in that window. Look at its error rate and latency using the signals in what to monitor on an internal package mirror.
- Add a concurrency cap on the heaviest pipeline first, usually the matrix build.
- Stagger scheduled jobs that start on the hour.
- Rerun the same peak scenario and compare. Keep what helped.
What not to do
Do not raise connection settings to make installs faster in a fleet. It may help on one laptop and hurt a shared mirror. Do not remove retries entirely either, since transient errors are real. The aim is to bound the peak and keep retries polite. Settings are compared in how long npm, pip and cargo retry a dead registry.
Where Safeguard fits
Safeguard's SBOM and dependency scanning can show which pipelines pull the same large dependency sets, which is a good place to start caching. A free scan is available at gold.safeguard.sh/scan.
Quick check
Does lowering maxsockets fix a mirror overload?
It reduces load per install, but the better fix is fewer repeated downloads through a cache and a cap on job concurrency.
Is staggering worth it for a few jobs?
For a handful, no. It matters when many jobs share one trigger time, such as a nightly schedule across many repositories.
Sources
Last reviewed: 19 October 2026.