{{ summaryTitle }} {{ summaryValue }} {{ summaryLine }}
Planned load: {{ averageBadge }}
Peak clear: {{ queueBadge }}
Active cap: {{ capBadge }}
CI runner capacity setup
Runner pool workload and capacity inputs
The name is carried into result tables and downloaded documents.
Use the slots available to this pool before any platform concurrency cap.
slots
Use 24 for an always-on pool; account for additional availability loss in Advanced only once.
hr/day
A lower target reserves more headroom and can increase the recommended slot count.
%
This is a planning target, not a prediction of individual workflow wait time.
min
If this count already includes retries, leave the Advanced retry rate at zero.
jobs/day
Use a representative occupied-duration mean for the same pool and period as job volume.
min/job
Use 1 for no concentration; derive higher values from queued and running jobs during peak hours.
× average
{{ workflowFeedback }}
Leave zero when the current slot count already represents the enforced limit.
slots
Leave zero when request limits are unknown or not relevant to this pool.
requests
Leave zero when jobs per day already includes all retries.
%
Leave zero when usable hours already account for this loss.
%
{{ planExportStatus }}
Planning itemResultUseCopy
{{ row.item }}{{ row.result }}{{ row.use }}
{{ checksExportStatus }}
CheckStatusOperator actionCopy
{{ row.check }}{{ row.status }}{{ row.action }}
{{ chartExportStatus }}
{{ summaryAnnouncement }}

A continuous integration (CI) runner pool can look adequate over a whole day and still build a queue during the busiest merge or release hour. Daily workload measures sustained demand. Peak concentration, platform caps, pickup behavior, failures, and autoscaler delay determine whether jobs start when the team expects them to.

The useful planning unit is an occupied runner-minute. A nine-minute job consumes nine minutes of one concurrent slot, including checkout, setup, cache restore, execution, artifact upload, and teardown whenever the slot stays occupied. Multiplying occupied duration by submitted jobs makes different runner pools easier to compare than counting jobs alone.

CI runner capacity terms and planning effects
QuantityPlanning useMisread to avoid
Runner slotOne job that can execute concurrentlyCounting hosts when each host supports several jobs.
Target utilizationShare of available runner time reserved for normal demandPlanning at 100% and leaving no room for variation.
Busy-hour multiplierConcentration of runner-minutes in the peak hourUsing a daily average as if arrivals were uniform.
Concurrency capMaximum active jobs allowed by a platform, group, or scale setAdding nominal slots without raising the binding cap.
Pickup concurrencyRequests that can wait for new jobs at onceTreating pickup requests as execution capacity.

Headroom is a policy choice rather than wasted capacity. Image pulls, noisy neighbors, maintenance, larger-than-average jobs, retries, and sudden commit bursts all consume room that a perfect average does not show. A lower target utilization asks for more slots but makes the plan less sensitive to those variations.

Queue time is especially difficult to predict from summary data. This capacity model represents one busy hour as excess runner-minutes and estimates how long the pool takes to drain that excess after accounting for ongoing average demand. It does not reconstruct individual arrival times, workflow dependencies, job priorities, matrix fan-out, or autoscaler startup.

Use a consistent measurement window for job count and occupied duration, and split pools that serve materially different executors or hardware. A blended average across Linux, macOS, GPU, privileged, or region-specific jobs can recommend slots that no actual queue can use.

How to Use This Tool:

Define one runner pool, measure its completed workload over a representative period, and add the limits that can prevent nominal slots from accepting jobs.

  1. Name the Runner pool and enter equivalent Current runner slots. Count concurrent job positions rather than physical machines.
  2. Set Usable hours per day and Target utilization. Use 24 hours for an always-on pool, then record maintenance or autoscaler loss under unavailable capacity only once.
  3. Enter Jobs per day and representative Occupied minutes per job from the same pool and period. If the job count already includes reruns, leave additional retry rate at zero.
  4. Set the Busy-hour multiplier from observed queued and running work during peak periods, then choose the maximum acceptable Peak wait SLA for draining the modeled excess.
  5. Add a configured concurrency cap, pickup request concurrency, retry load, and unavailable capacity when they apply. Read Capacity plan for recommended slots and Operating checks for any cap, queue, or pickup warning.

Interpreting Results:

Average-day minimum is the smallest whole slot count that fits daily runner-minute demand inside the selected utilization target. Recommended slots can be higher because they must also drain the modeled peak excess within the queue-clear target.

  • Effective slots is the lesser of nominal slots and a positive configured cap. A binding cap can make added runners invisible to active-job capacity.
  • Planned utilization above 100% means daily demand exceeds capacity after target utilization and unavailability are applied.
  • Peak clear time estimates how long excess work from one modeled busy hour takes to drain. It is not a prediction for an individual job.
  • A pickup warning means the entered request concurrency is below effective execution slots. Check platform behavior and long-polling metrics before changing it.
  • Compare repeat runs only when pool boundaries, measurement window, job-duration definition, retry treatment, and usable hours stay consistent.

Technical Details:

Daily demand is adjusted for retry work and converted to runner-minutes. Each slot contributes usable minutes after the unavailable-capacity allowance, and only the target-utilization share is planned for normal work.

Formula Core:

The average-day calculation uses the following quantities.

Jadjusted=J(1+r) D=JadjustedM Cslot=60H(1-u)t Naverage=ceil(DCslot)
CI runner formula symbols and units
SymbolMeaningUnit
JSubmitted jobs per day before additional retry loadjobs/day
rAdditional retry rate as a decimalRatio
MAverage occupied minutes per jobminutes/job
HUsable operating hours per dayhours/day
uUnavailable-capacity shareRatio
tTarget utilization shareRatio
DAdjusted daily runner-minute demandrunner-minutes/day

A positive concurrency cap replaces nominal slots with the smaller capped value for current-capacity checks. Actual utilization divides demand by all available runner-minutes; planned utilization divides it by the target-utilization share.

Peak Queue Mechanism:

The busy-hour multiplier applies to average runner-minute demand per hour. Excess is the portion above planned hourly capacity. Drain rate is the available concurrent work rate after subtracting ongoing average demand, with a small positive floor to keep the estimate finite.

P=DHb X=max(0,P-60N(1-u)t) q=max(0.1,N(1-u)-D60H) Tclear=Xq

b is the busy-hour multiplier, P is peak runner-minutes per hour, X is excess runner-minutes, and q is runner-minutes cleared per wall-clock minute. Recommended slots are found by testing whole counts from the average-day minimum upward until planned utilization is at most 100% and peak clear time is at most the entered target. The search does not assume a configured cap can be raised; a lower cap is reported separately as blocking the plan.

CI runner result rule order
StatusRule
Cap blockedA positive configured cap is below recommended slots.
Average shortfallPlanned utilization is greater than 100%.
Queue target missPeak clear time is greater than the selected target.
Pickup reviewA positive pickup request concurrency is below effective slots.
HealthyNone of the earlier rules applies.

Whole-slot requirements round upward. Other calculations retain full numeric precision before display formatting. Inputs allow up to 100,000 slots; a workload requiring more is rejected rather than silently capped as a valid plan.

Limitations:

The queue-clear result is a deterministic planning approximation, not a discrete-event simulation or a service-level guarantee.

  • One average duration does not capture long-tail jobs, workflow dependencies, priorities, cancellation, or matrix fan-out.
  • The busy-hour multiplier models one concentrated hour. It does not reproduce the timing of individual arrivals or several consecutive peaks.
  • Unavailable capacity is a single percentage and cannot separately model autoscaler startup, image pulls, executor failures, or maintenance windows.
  • Platform concurrency limits and runner settings change. Check the current account, group, runner, and hosting limits rather than copying a generic value.
  • Pickup concurrency is a diagnostic input. Its meaning depends on the CI platform and runner configuration, and increasing it does not create execution slots.

Worked Examples:

Shared Linux pool at the default workload

Nine hundred jobs at 9 occupied minutes create 8,100 runner-minutes per day. With 20 usable hours, 70% target utilization, and no retry or availability loss, each slot contributes 840 planned minutes. The average-day minimum rounds up to 10 slots, but a 1.35 busy-hour multiplier needs 12 slots to clear the modeled excess in about 8.14 minutes, inside a 10-minute target.

Release burst needs more peak capacity

Keeping the same daily workload but increasing the busy-hour multiplier to 1.6 does not change the 10-slot average minimum. Twelve slots would take about 27.43 minutes to drain the modeled excess, so the recommendation rises to 14 slots for the 10-minute target. A configured cap below 14 would still block that plan even if 14 nominal slots were provisioned.

References: