{{ result.summaryTitle }}
{{ result.primary }}
{{ result.summaryLine }}
{{ badge.label }}
CI runner capacity inputs
Names the pool in exports and guidance rows.
Use equivalent slots when one machine can run more than one job.
Use 24 for always-on runners or a smaller build-day window.
hr/day
Lower targets reserve burst, image-pull, maintenance, and autoscaler headroom.
%
Used to flag burst hours that fit average capacity but still create visible CI wait time.
min
Use recent scheduler or CI analytics volume for the same labels and runner group.
Use runner-occupied duration, not just test execution time.
min
Use recent queued/in-progress job patterns when peak hours are much busier than the daily average.
Leave 0 when runner count already represents the enforced concurrent job limit.
Leave 0 when pickup request limits are unknown or not relevant to this runner pool.
Leave 0 when jobs per day already includes retries.
%
Leave 0 when runner hours already include availability loss.
%
Capacity metricValueReadoutCopy
{{ row.metric }}{{ row.value }}{{ row.readout }}
CheckStatusActionCopy
{{ row.check }}{{ row.status }}{{ row.action }}
RunnersUtilizationHeadroomPeak clearQueue noteCopy
{{ row.runners }}{{ row.utilization }}{{ row.headroom }}{{ row.peakClear }}{{ row.note }}
Customize
Advanced
:

Introduction

CI runner capacity is the amount of build and test work a runner pool can finish without creating avoidable queue time. The useful unit is runner-minutes: one runner slot available for one minute. A pool with many runners can still feel slow when jobs arrive in bursts, runtimes grow, or a platform cap lets fewer jobs run than the hardware count suggests.

Capacity planning matters most when CI is shared by many teams or when self-hosted runners have a real cost. A pool that averages 50% use may still block developers during a merge window if most jobs arrive in the same hour. A pool that looks fully used may also be healthy when the team intentionally runs close to capacity and accepts a longer queue target.

Job volume jobs per day Runtime minutes per job Runner slots hours x reserve Headroom spare runner-min Queue risk peak clear time The same daily demand can pass or fail depending on usable hours, target utilization, burst size, and concurrency caps.

The main planning question is not just how many runners exist. It is how much useful runner time remains after maintenance windows, autoscaler lag, image pulls, failures, retry load, and deliberate utilization reserve. A sustainable target below 100% leaves room for job pickup delay, uneven arrivals, and short periods of overload.

A runner capacity estimate is a planning model, not a live CI scheduler report. It is strongest when the inputs come from the same runner label, group, executor tier, or queue that will receive the work. Mixed pools, different machine sizes, long setup times, and platform-specific throttles should be modeled as separate pools or included through the cap and unavailable-capacity settings.

Technical Details:

Runner capacity starts with demand. Daily runner demand is the adjusted job count multiplied by average runner-occupied runtime. Runtime should include setup, checkout, dependency restore, container startup, test execution, teardown, and any other time that keeps the slot busy.

Useful capacity is lower than nominal machine time when the pool is not available all day or when a utilization reserve is kept on purpose. A 12-slot pool available for 20 hours has 14,400 nominal runner-minutes per day. At a 70% target, only 10,080 runner-minutes are treated as planned capacity, leaving the rest as burst and operating reserve.

adjusted jobs = jobs per day×(1+retry rate) daily demand = adjusted jobs×average job minutes planned capacity = effective slots×hours per day×60×(1-unavailable rate)×target utilization average-day slots = daily demandplanned capacity per slot

Effective slots are the slots that can actually run jobs for the modeled pool. When a configured concurrency cap is entered, effective slots become the lower of runner count and the cap. That mirrors CI systems where worker count, group limits, or autoscaling maximums can hold useful capacity below the number of registered machines.

CI runner capacity quantities and effects
Quantity How it affects the estimate Boundary used by the calculator
Runner count Sets nominal concurrent runner slots. Must be greater than 0.
Usable runner hours Limits how many minutes each slot can serve in one day. Must be greater than 0 and no more than 24 hours.
Target utilization Reserves capacity before the average-day slot count is judged healthy. Must be from 1% to 100%.
Jobs per day and average job time Produce daily runner-minute demand. Job count cannot be negative; runtime must be positive when jobs are present.
Busy-hour multiplier Raises peak hourly demand above the daily average. Must be at least 1.
Concurrency cap Reduces effective slots when a platform or runner manager cap is lower than runner count. 0 means no extra cap is modeled.
Request concurrency Flags a job-pickup risk when request slots are lower than active runner slots. 0 means no request-pickup limit is modeled.
Retry rate and unavailable capacity Retries add demand; unavailable capacity removes usable runner time before utilization and queue math. Retry cannot be negative; unavailable capacity is allowed from 0% to 95%.

Peak queue pressure compares one busy hour against planned hourly capacity. The model estimates the runner-minutes that exceed the planned hourly capacity, then divides that backlog by the remaining clear rate after average work continues arriving. The result is peak clear time, which is compared with the queue wait target.

peak demand per hour = daily demandusable runner hours×busy-hour multiplier peak deficit = max(0,peak demand per hour-planned hourly capacity) peak clear time = peak deficitclear rate per minute

The peak slot count and peak clear time are related but not identical. Peak slot count asks how many slots would cover the busy-hour throughput at the chosen utilization target. Peak clear time asks whether a temporary busy-hour backlog clears inside the wait target while average demand continues. That is why a pool can show a busy-hour slot shortfall and still meet a 10 minute clear target when the average-day reserve is large enough.

Everyday Use & Decision Guide:

Start with one runner pool, not the whole CI estate. Put the label, runner group, executor tier, or queue name in Runner pool. Use Runner count for equivalent concurrent slots, so a machine that safely runs two jobs counts as two slots only when the platform and hardware are configured that way.

The first useful pass should come from recent CI history. Set Jobs per day to all successful, failed, and canceled jobs submitted to that same pool. Set Average job time to runner-occupied minutes, not just test minutes. If retry jobs are already included in the job count, leave Retry rate at 0 to avoid counting them twice.

  • Use Usable runner hours as 24 for always-on runners, or the actual build-day window for scheduled or cost-controlled runners.
  • Use Target utilization below 100% when image pulls, queue unevenness, maintenance, and autoscaler lag need reserve.
  • Set Busy-hour multiplier from the busiest merge, release, or morning commit period rather than from the daily average.
  • Enter Configured concurrency cap when a runner manager, scale set, or platform limit is lower than the runner count.
  • Use Request concurrency when job pickup itself can bottleneck before all slots are busy.
  • Use Unavailable capacity for time lost to maintenance, failed nodes, cold images, or autoscaler delay that is not already removed from usable hours.

Runner Capacity is the first readout for daily fit. It shows effective runner slots, daily runner demand, planned capacity, target utilization used, average-day slots, busy-hour slots, peak clear time, and average concurrency. Queue Pressure Audit turns those numbers into specific checks for average margin, peak wait target, caps, pickup requests, retries, availability loss, and burst pressure.

The charts help compare choices before changing infrastructure. Runner Capacity Curve shows how planned runner-minutes move as runner count changes, while Peak Wait SLA Curve shows how many slots are needed to clear the modeled burst inside the wait target. A high runner count does not prove the pool is healthy if the effective slots are capped or if peak clear time remains above the target.

This estimate is a good fit for scaling reviews, budget planning, and before-and-after comparisons when changing runner count, utilization reserve, or job runtime. It is not a substitute for scheduler telemetry. Before raising the cap or buying more runners, check whether long jobs can be split, flaky retries can be reduced, stale labels can be retired, or the busy-hour multiplier comes from one temporary release event.

Step-by-Step Guide:

Build the model from the current pool first, then use the scenario and chart outputs to test changes.

  1. Name the pool with Runner pool. The summary title should use that label so copied rows remain tied to the right queue or runner group.
  2. Enter Runner count, Usable runner hours, Target utilization, and Queue wait target. The summary should show active slots and a peak clear time compared with the target minutes.
  3. Enter Jobs per day, Average job time, and Busy-hour multiplier. Daily runner demand should equal adjusted jobs multiplied by average runtime, and Busy-hour slots should rise when the multiplier rises.
  4. Open Advanced for Configured concurrency cap, Request concurrency, Retry rate, and Unavailable capacity. A binding cap should change Effective runner slots, and a low request value should appear in Pickup requests.
  5. Read Runner Capacity before changing the pool. If Target utilization used is above 100%, average daily demand exceeds planned capacity.
  6. Open Queue Pressure Audit. If Peak wait target says the burst clears too slowly, compare the suggested slot count with the current cap and the busy-hour multiplier.
  7. Use Runner Scenario Table, Runner Capacity Curve, and Peak Wait SLA Curve to compare nearby runner counts. Keep the same pool assumptions while comparing rows.
  8. If the input review alert appears, fix the named fields before using the result. Runner count must be above zero, usable hours must be 0.1 to 24, target utilization must be 1% to 100%, queue wait must be above zero, and unavailable capacity must stay at or below 95%.

Interpreting Results:

Daily runner demand and Planned capacity carry the average-day answer. When demand is below planned capacity, the pool has average headroom at the selected utilization reserve. When demand is above planned capacity, more slots, shorter jobs, fewer submitted jobs, a lower retry rate, or more usable hours are needed before burst behavior is even considered.

Peak clear time is the main wait cue. It estimates how long the modeled busy-hour backlog takes to drain against the queue wait target. A peak clear result under the target does not promise that no job waits; it says the modeled burst can be cleared within the chosen target under the current assumptions.

Average-day slots and Busy-hour slots should be read with the cap fields. If Configured concurrency cap is lower than runner count, adding machines may not improve useful capacity until the cap is raised. If Pickup requests is lower than active slots, jobs can wait even while nominal runner capacity exists.

CI runner capacity result fields and follow-up checks
Result field What it means What to verify next
Effective runner slots Useful concurrent slots after any configured cap. Compare with runner group limits, scale-set maximums, and executor capacity.
Target utilization used Daily demand divided by planned capacity. Investigate when it exceeds 100% or stays close to the target for long periods.
Peak clear time Estimated drain time for the modeled busy-hour backlog. Compare with the queue wait target and with real queued-duration percentiles.
Average margin Runner-minutes left or missing after average daily demand. Use it to decide whether runtime reduction or runner count has the larger effect.
Busy-hour pressure The selected burst multiplier applied to average hourly demand. Confirm the multiplier comes from current CI analytics, not a one-off incident.

Worked Examples:

Shared Linux pool with moderate burst

The default-style setup uses 12 runner slots, 20 usable hours, a 70% target, a 10 minute queue wait target, 900 jobs per day, 9 minutes per job, and a 1.35x busy-hour multiplier. Daily runner demand is 8,100 min, Planned capacity is 10,080 min, and Target utilization used is about 80.4%. The model reports Average-day slots as 10, Busy-hour slots as 14, and Peak clear time near 8.1 min, so the burst is tight but still clears inside the selected target.

Mobile build pool blocked by caps

A mobile pool with 18 runners, 22 usable hours, a 65% target, 1,400 daily jobs, 11 minute jobs, a 1.6x busy-hour multiplier, a 14 slot concurrency cap, 6% retry load, and 8% unavailable capacity has only 14 effective runner slots. Adjusted demand reaches about 16,324 min, while planned capacity is about 11,051 min. Target utilization used is about 147.7%, Average-day slots is 21, and Peak clear time is about 22.2 hr. Adding machines alone will not help while the cap remains at 14.

Average capacity passes but peak wait fails

A pool with 10 runners, 20 usable hours, a 70% target, 720 jobs per day, 8 minute jobs, and a 2.4x busy-hour multiplier has about 5,760 min of daily demand against 8,400 min of planned capacity. Average demand fits at about 68.6% target utilization, but Peak clear time rises to about 52 min against a 10 minute target. The Peak Wait SLA Curve points toward roughly 15 slots, unless the busy-hour multiplier can be reduced by spreading scheduled jobs.

Small pool with intentional reserve

A smaller pool with 6 runners, 16 usable hours, a 75% target, 360 jobs per day, 6.5 minute jobs, a 1.25x peak, and 5% unavailable capacity produces about 2,340 min of daily demand. Planned capacity is about 4,104 min, Target utilization used is about 57.0%, and Peak clear time is 0.0 min because planned hourly capacity covers the modeled burst. The spare runner-minutes are real reserve, but they may still be justified if the pool protects release jobs or expensive integration tests.

Input review before interpretation

If Runner count is 0, Usable runner hours is above 24, Queue wait target is 0, or Unavailable capacity is above 95%, the summary changes to Check values. Fix those inputs before reading Runner Capacity or charts. Validation failures are not capacity findings; they mean the model has not received a valid runner pool definition.

Responsible Use Note:

Runner pool names, job volumes, runtimes, concurrency caps, and queue targets can reveal engineering scale, release cadence, and infrastructure constraints. Use neutral pool names when sharing copied rows outside the team, and avoid putting customer names, private project labels, or sensitive release names into the pool label.

The calculation runs in the browser after the page loads. It does not inspect a live CI system, change runner settings, or provision capacity. Treat the output as planning evidence that should be compared with CI queue duration, runner utilization, job duration percentiles, and platform limits from the same pool.

FAQ:

What counts as one runner slot?

Use one slot for one job that can run at the same time. If a single host can safely run two concurrent CI jobs and the CI platform allows both, count it as two slots. If a cap allows only one job, count one effective slot.

Should average job time include setup?

Yes. Use runner-occupied time, including checkout, image startup, dependency restore, test runtime, artifact upload, and teardown when those steps keep the slot busy.

Why can average capacity pass while peak wait fails?

Average capacity uses total daily runner-minutes. Peak wait uses the busy-hour multiplier and queue wait target. A pool can have enough minutes across the day but still need more slots when many jobs arrive at the same time.

Why does a concurrency cap matter if I have more machines?

A lower cap limits effective runner slots. When Configured concurrency cap is below Runner count, the capacity rows use the capped value because extra registered machines cannot run more jobs until the cap changes.

What should I do when peak clear time is too high?

Check Queue Pressure Audit first. The fix may be more slots, a higher cap, lower runtime, fewer retries, a lower busy-hour multiplier, or job scheduling changes that spread work away from the busiest hour.

Why am I seeing Check values?

One or more inputs are outside the supported range. Runner count and queue wait target must be above zero, usable runner hours must be no more than 24, target utilization must be 1% to 100%, and unavailable capacity must be at most 95%.

Glossary:

Runner slot
One concurrent job position in the modeled runner pool.
Runner-minute
One runner slot available or occupied for one minute.
Effective runner slots
The useful slot count after applying a configured concurrency cap when one is modeled.
Target utilization
The planned sustainable share of available runner time, leaving reserve for burst and operating overhead.
Busy-hour multiplier
The factor used to raise average hourly demand to the expected busiest-hour demand.
Peak clear time
The estimated time needed to drain the modeled busy-hour backlog against continuing average demand.
Request concurrency
A job-pickup request limit that can delay assignment before all runner slots are busy.