Cycle time is shaped by several factors: how heavily the team is loaded, how evenly work arrives, and how much individual items vary in size — a password reset versus a new feature. The variation terms are usually the largest contributors to queue time, and almost never the ones that get measured.
Most teams focus on capacity — are there enough people, is everyone busy enough. Load matters, but variability is usually the larger driver of delay.
Kingman’s formula captures all three. It predicts how long work waits before anyone touches it, from utilisation and the two variability terms.
The time spent working on an item — coding, reviewing, testing. The minimum cycle time any item can have.
Time spent waiting after commitment but before someone starts working — queued for a developer, waiting in a review queue, held at an approval step.
Total elapsed time from commit to done. Cycle time = touch time + queue time. In most teams, the queue part dominates.
The chart below starts with zero variability — every ticket the same size, work pulled in at a steady rate, team at 80% load. With no variance, there is no queue: cycle time equals touch time.
Raise either variability dial and cycle time climbs. The more loaded the team, the harder it hits. That is Kingman’s formula in a sentence: load amplifies variability. Neither causes queues alone; together they multiply.
The six experiments below step you through each permutation in turn.
-
Both variability dials at zero — drag utilisation all the way upships just as fast
Even near full capacity, the process flows smoothly — cycle time barely moves. With zero variability, load alone cannot create a queue. ↺ reset defaults before the next step.
-
Raise cycle-time variability to ~1.5 — leave arrival variability at zerotakes longer to ship
Queue time climbs — utilisation unchanged. Big tickets block small ones; the queue forms naturally. The team is no busier; the work is just less uniform in size.
-
Keep cycle-time variability at ~1.5 — bring utilisation down to 0.60shipping speeds up
Cycle time improves even though ticket sizes haven’t changed. Slack gives smaller tickets room to get through. The trade-off is lower throughput — fewer items arrive and complete per unit time — but each one waits far less. ↺ reset defaults before continuing.
-
Raise arrival variability to ~1.5 — leave cycle-time variability at zerotakes longer to ship
Same slowdown, different cause. Tickets arriving in bursts pile up even when every ticket is the same size. Either type of variability is enough on its own. ↺ reset defaults.
-
Now raise cycle-time variability to ~1.5 as well — both dials upmuch longer to ship
Both sources compound each other. Lumpy ticket sizes and irregular commit cadence at the same time — this is the typical real-world condition.
-
Keep both dials at ~1.5 — bring utilisation down to 0.50shipping speeds up
Even with both variabilities high, lowering utilisation brings cycle time back down. Spare capacity is the universal antidote: it can’t remove the variability, but it absorbs it. The cost is lower throughput.
The key interaction: load amplifies variability
Variability and load don’t add — they multiply.
- — If variability is zero — every ticket the same size, work committed at a perfectly steady rate — the queue is zero no matter how loaded the team is. You can run at 99% and work still flows. Variability is the signal.
- — If the team is lightly loaded, even high variability is absorbed by the gaps. Load is the amplifier.
A fully-loaded team has no slack left to absorb the variability that’s already there. At 70%, a large ticket falls into the gaps. At 95%, it has nowhere to go and cycle time runs away.
High utilisation is only a problem when variance is high
Variance is always present in a real backlog. Sprint planning drops two weeks of tickets into the queue on Monday. Urgent bugs land between planned items. Tickets range from a config change to a two-week feature. That variance is always in the system, waiting to be amplified — and the higher the utilisation, the harder it hits.
The busyness trap
The pressure in most teams is to fill everyone’s time — 100% utilisation, no unallocated hours. Idle capacity looks like waste.
Kingman’s formula says what happens. Near full capacity, U = ρ/(1−ρ) accelerates fast. You gain almost no throughput (you were near capacity already) while cycle time climbs steeply — because the spare capacity you removed was exactly what was absorbing the variance. The team feels productive; delivery slows.
What you can control
Touch time and cycle-time variability are largely fixed:
- — Touch time (T) is largely fixed. Better tooling, CI, or automation can reduce it, but slowly — it’s not a lever you pull day to day.
- — Cycle-time variability (c_s²) is mostly intrinsic. A one-line bug fix and a two-week feature are different sizes of work. Breaking large items into smaller ones reduces the spread but doesn’t eliminate it.
Two inputs are directly controllable:
- Utilisation (ρ) — controlled with a WIP limit. Capping how many tickets are in flight directly caps how steeply the queue multiplier climbs.
- Arrival variability (c_a²) — controlled with a pull mechanism. Pulling one ticket when a slot frees up, instead of committing a batch of work at the start of a cycle, turns a batch arrival into a smooth stream.
Almost everything you can do to reduce cycle time runs through those two controls.
Lever 1: a pull mechanism (smooths arrivals)
Sprint planning that commits two weeks of work in one session delivers a batch to the queue — high arrival variability. Pulling one ticket in only when a slot frees up delivers a stream. Same total work, same capacity, lower queue time. Work enters as a stream rather than a batch — same total volume, lower arrival variability.
Plan the order, not the batch: decide priority in advance, pull from the top of that list, and don’t add the next item until there’s a slot for it.
Lever 2: a WIP limit (caps utilisation)
Cap the number of tickets in flight. Because the cost of load is non-linear, the region above ~85% utilisation is where cycle time accelerates — a WIP limit keeps you below it. That spare capacity absorbs the variance you can’t remove.
(These two are closely linked — a WIP limit is a pull mechanism in practice, since you can only pull new work when you’re under the limit. Together they control both utilisation and arrival variability.)
The formula
For a single work stream (one team, one queue), the average time a ticket spends waiting before anyone touches it is approximated by:
VUT equation — Variability × Utilisation × Time
This is Kingman’s formula, also called the VUT equation. It approximates a G/G/1 queue — general arrival distribution, general cycle-time distribution, one server — and is known to be accurate, especially when the system is heavily loaded. The exact G/G/1 queue has no closed-form solution — Kingman’s is the best available.
Three terms, each independent:
| Term | Name | What it is |
|---|---|---|
| U = ρ / (1 − ρ) | Utilisation factor | How loaded the team is. ρ is the fraction of capacity in use (0 to 1). |
| V = (c_a² + c_s²) / 2 | Variability factor | The average of two squared coefficients of variation — one for arrivals, one for cycle time. |
| T | Touch time | Mean time to do the work, hands-on, uninterrupted. |
The total cycle time a ticket experiences — commit to done — is queue time plus touch time:
The whole point of the formula is that queue time is usually the larger part, and it’s the part nobody measures.
Reading the three terms
T — touch time
Just the work itself. A one-line fix has a small T; a multi-day feature has a large one. T sets the scale of the queue term but isn’t where the leverage is.
V — variability
V is the average of two squared coefficients of variation (CV = standard deviation ÷ mean). A CV of 0 means perfectly uniform; a CV of 1 means the spread equals the mean — typical of random, memoryless arrivals; above 1 means highly erratic.
Two sources feed into it:
- c_a² — arrival variability. How evenly work is committed into the process. Pulling one item in whenever a slot frees up is low. Committing a fortnight’s work in one Monday planning session is high.
- c_s² — cycle-time variability. How much the items themselves differ in size. A queue of identical password resets is near zero. A mix of a typo fix, a gnarly defect, and a feature is high.
Because the formula adds the squares, the more erratic of the two dominates. If arrivals are smooth (c_a² = 0.2) but ticket sizes are wild (c_s² = 4), V is driven almost entirely by the second.
U — utilisation, and why it’s the dangerous one
U = ρ / (1 − ρ) is the term that makes the whole thing non-linear. As ρ approaches 1 (100% loaded), the denominator approaches 0 and U explodes:
| Utilisation ρ | U = ρ/(1−ρ) | Relative queue time |
|---|---|---|
| 50% | 1.0 | 1× (baseline) |
| 70% | 2.3 | 2.3× |
| 80% | 4.0 | 4× |
| 90% | 9.0 | 9× |
| 95% | 19.0 | 19× |
| 99% | 99.0 | 99× |
Going from 80% to 95% utilisation doesn’t add a little queue time — it multiplies it by roughly five. The cost of load is not linear, it accelerates. The last few percent of utilisation are catastrophically expensive.
Takeaways
- — Measure commit-to-done. Most of that time is usually queue time — the wait before someone picks the ticket up. You can’t fix it if you don’t measure it.
- — If everyone is busy but delivery is slow, check utilisation. Above ~85%, any variance in the system compounds. A team feeling productive and delivery being slow are consistent states under Kingman.
- — Sprint capacity targets that fill to 100% are utilisation targets. They trade cycle time for the appearance of efficiency. Leaving 15–20% unallocated is how you preserve the slack that absorbs variance.
- — Only two things are directly controllable: WIP and the pull mechanism. A WIP limit caps utilisation; pulling one ticket at a time smooths arrivals. Touch time and item-size variance are mostly given.
- — When cycle time is high, check the queue-time share first. If most of the wait is queuing rather than touching, adding people won’t help — only lowering variability or utilisation will.
- — Expect a lag after any change. It takes about a cycle to reach a new steady state. Don’t judge an intervention on its first cycle.