02

Managing queues: the invisible inventory

Most of the delay in product development is not work, it is waiting. Work-in-process here is information (specs, designs, test builds) that sits in queues no one can see. Queueing theory says those queues grow explosively as utilization approaches 100%, grow linearly with variability, and drift like random walks. Reinertsen's conclusion: stop optimizing for busy people, measure and control queue size directly, and pick utilization by economics, not by habit.

Inventory you cannot see

Q1Q2
The same queue looks very different on a factory floor and in an engineering org. Drag the queue size and compare what each organization notices, then read what those items cost.

Factory: inventory is physical

$68k on the balance sheet
parts piled in front of each machineCut5 waitingMill11 waitingWeld8 waitingPaint10 waiting

A pile of 34 parts blocks the aisle; the CFO sees $68k of inventory. Someone acts.

Engineering: inventory is information

$0 on the balance sheet
specs, designs, branches waiting at each hand-offSpecqueue: ?busy ✓Designqueue: ?busy ✓Buildqueue: ?busy ✓Testqueue: ?busy ✓

Everyone looks 100% busy. The queue lives in inboxes, ticket trackers and branches, so no one sees it.

What 34 invisible items cost (Q2)

longer cycle time
+6.8 wk
Little: 34 items ÷ 5/wk
cost of delay
$510k/wk
34 items × $15k/item-wk
more risk
19%
chance requirement goes stale (3%/wk drift)
more variability
±6.8 wk
queue time is roughly exponential: spread ≈ mean
more overhead
17 h/wk
status, re-planning, re-prioritizing @0.5h/item
lower quality, less motivation
6.8 wk
before anyone uses (and checks) what you just finished

Try: x-ray the queues, then drag the queue per hand-off to 20. Nothing in the manager's view changes, yet cycle time grows by weeks and the weekly cost of delay passes a team's payroll.

Product-development inventory is design-in-process: information, not parts. It has no physical footprint and no line on the balance sheet, so the measurement system that makes factories fight inventory is simply absent. The first step is to count it.

The hockey stick: utilization and variability

Q3Q5Q6
Exact M/M/1 and M/D/1 results, plus Kingman's approximation for general variability. Utilization acts through 1/(1−ρ); variability acts as a linear multiplier.

Queue vs capacity utilization

M/M/1 (random arrivals, random work)M/D/1 (random arrivals, fixed work)G/G/1 Kingman (Ca²=1, Cs²=0.25)
010200%20%40%60%80%100%capacity utilizationitems in system85%

Try: drag ρ from 80% to 95% and watch the red curve go vertical. Then set Cs² to 0 (fixed task sizes): the purple curve halves but keeps its hockey-stick shape. Shaded box: queue range for a ±5-point swing in load (Q6).

M/M/1 at 85%
5.7
items in system (L)
cycle time
6.7× work time
M/M/1: W/s = 1/(1−ρ)
80% → 90%
×2.25
L: 4 → 9 items
+1 pt of load adds
0.47 items
variability amplification, dLq/dρ
±5 pt load swing
4.0 – 9.0
items in system (L)

Variability (Q5)

Kingman: Lq ≈ ρ²/(1−ρ) · (Ca²+Cs²)/2. Variability scales the queue linearly(now ×0.63 vs M/M/1); utilization acts through 1/(1−ρ).

A live queue: random walks and high-queue states

Q4Q12
A single server with Poisson arrivals and exponential work times. The queue is never steady: it wanders, and the rare long-queue periods carry most of the total delay. Little's Law is checked live.

One server, Poisson arrivals

t = 0 work-times
arrivals →server0 waiting · color = time waited

Items in system over time: a random walk

0510050100150200time (work-times)itemstheory L = 5.7

Try: run at 70%, then 95%. The average hides long excursions; the queue wanders, drifts, and stays high for a long time.

Where the delay comes from (Q4)

high-queue states (N ≥ 15)0510152025items in system N (last bin = 25+)
■ share of time■ share of total delay (item-time)— theory (1−ρ)ρⁿ
L (avg in system)
0.00
theory 5.67
λ (arrival rate)
0.000
set 0.85 / work-time
W measured
0.00
0 jobs finished
Little: L ÷ λ
0.00
W = L / λ
time with N ≥ 15
0.0%
theory 8.7%
delay from N ≥ 15
0%
theory 32%

Now 0 in system. Little's Law (Q12) holds for any stable queue: the measured L ÷ λ converges to the measured average cycle time W whatever the distributions. Speed up to 40× to let it settle.

Structure: pooled queues and linked queues

Q7Q8
The same people and the same demand produce very different queues depending on how the work is routed, and on how loaded the step upstream of a bottleneck is.

Queueing structure (Q7)

4 separate queues1 pooled queue, 4 servers4μ1 server, 4× faster
separate queues
6.67×
wait 5.67
pooled queue
2.15×
wait 1.15
one fast server
1.67×
wait 1.42

Mean cycle time, in multiples of one engineer's work time per job (M/M/1 vs M/M/4 with Erlang C).

pooling cuts cycle time
3.1×
jobs that wait at all (pooled)
69%
vs 85% with separate queues

Try: raise utilization to 95% with 6 engineers: separate queues take 20× the work time, the pooled queue far less. The fast single server wins on paper, but if it goes down everything stops.

Linked queues (Q8)

Ca²=2.0upstream50% · Cs²=0.2departures Cd² = 1.55ρ²·Cs² + (1−ρ²)·Ca²bottleneck85% · Cs²=1Lq 6.1
downstream sees
mostly arrival variability
weight on upstream Cs²: 25%
bottleneck queue
6.1
range 2.9 (full load) – 7.2 (idle)

Try: lumpy arrivals (Ca² = 3) into a predictable upstream step (Cs² = 0.2). At low load the lumps pass straight through to the bottleneck; load the upstream step to 95% and it releases work at its own steady rhythm, shrinking the downstream queue.

Pooling works because a shared queue never leaves an engineer idle while work waits in someone else's line, and one big job cannot trap everything behind it. Adjacent queues are coupled: whether a downstream process sees the upstream arrival pattern or the upstream service pattern depends on how loaded the upstream process is.

Choosing utilization with a U-curve

Q9
Neither 100% nor 50% utilization is right in general. The economic optimum minimizes the sum of what you pay for capacity and what the resulting queue costs in delay.

Total cost = cost of capacity + cost of delay

cost of capacitycost of delay (queue)total
$0$100k$200k$300k20%40%60%80%100%capacity utilization$ per weekoptimum 74%

Demand is 4 items/week; v = (Ca²+Cs²)/2 scales the queue; capacity costs $20k per (item/week) of capacity, so lower utilization means paying for more capacity. Try: raise cost of delay and watch the optimum slide left, away from 100%. Note how flat the bottom is.

economic utilization
74%
queue there: 2.1 items
minimum total
$137k/wk
if run at 95%
+101%
$274k/wk
if run at 50%
+24%
$170k/wk
forgiving range
59–85%
total within 10% of the minimum

Queueing discipline: the order matters

Q10
A queue of jobs with different durations and costs of delay. Total delay cost is Σ CoD × finish time; change the sequence and the same work costs very different amounts.

Sequence: FIFO

A6w · $17k$102kB3w · $11k$99kC3w · $14k$168kD2w · $8k$112kE2w · $10k$160kF4w · $10k

Bar = work (duration, cost of delay per week). Red shading = time spent waiting, darker for higher cost of delay. Each job costs CoD × finish time. Try: switch FIFO → WSJF and watch the dark red waits move to cheap jobs.

Total delay cost by policy

FIFO
$841k
shortest first
$753k
highest CoD first
$840k
WSJF (CoD ÷ duration)
$728k
FIFO vs WSJF
+16%
extra delay cost
this policy
$841k

With 2 jobs the order barely matters; with 12 it decides a large share of the cost. Sequencing is valuable when queues are big, but shrinking the queue reduces the delay of every job regardless of order.

Seeing queues: cumulative flow and Little's Law

Q11Q12
Plot cumulative arrivals and departures. The vertical gap is the queue, the horizontal gap is the time spent in it, and Little's Law (W = L ÷ λ) turns a queue count into a cycle-time forecast.

Cumulative flow diagram

cumulative arrivalscumulative departures
capacity ÷301002000204060daycumulative itemsqueue 265 days

Vertical gap (amber) = items in queue on that day. Horizontal gap (blue) = how long the item finishing that day spent in the system (FIFO). Slopes = demand and throughput. Try: inspect day 30 with the firefight on, then day 45 to see the gap close again.

queue on day 32
26
vertical gap
cycle time of that item
5 days
horizontal gap
Little forecast
8.7 days
queue 26 ÷ last-week throughput 3.0/day
avg queue ÷ avg throughput
2.1 days
9.3 ÷ 4.3/day
avg measured cycle time
2.1 days
over 260 finished items

Control queue size, not utilization or cycle time

Q13Q14
Demand surges for 30 days. Two controllers, tuned to the same threshold, add capacity: one watches the queue, the other watches the cycle time of finished work.

Queue size: leading indicator (shaded = surge)

no controlreact to cycle timereact to queue size
02040050100dayitems in queuelimit 12seen

Cycle time of finished work: lagging indicator

no controlreact to cycle timereact to queue size
024050100daydays (5-day avg)target 2.5dseen
surge visible in queue
day 39
demand jumps on day 30
surge visible in cycle time
day 45
6 days later
peak queue
50 / 29 / 27
none / cycle-time / queue control
peak cycle time
5 / 3 / 2
days, same order

Baseline load is 80% of capacity. Both controllers add 60% capacity while their trigger is on; the cycle-time target equals the queue limit converted by Little's Law, so they are tuned identically. Try: surge ×1.5 with limit 12. Queue control reacts the moment work piles up; cycle-time control waits until delayed items finally finish, by which time the queue is already large. Extra capacity days used: react to cycle time 8, react to queue size 7.

Why not control utilization (Q13)? It is hard to measure in knowledge work, and near the steep part of the curve an error of a few points in estimated utilization means a several-fold difference in queue. Queue size is a count you can take on a whiteboard today, and it leads cycle time (Q14), which you only learn when delayed work finally finishes.

Diffusion: queues drift out of control and stay there

Q15Q16
Thirty queues with identical average load. Each is a random walk; some wander far and take a long time to return. Randomness won't bring them back, intervention will.

30 independent queues, same average load

0102030400100200300400500time periodsqueue sizelimit 15

Each period: one arrival with probability 0.475, one completion with probability 0.5 (0.9 while intervening). Red = one highlighted path; dashed = σ√t, the random-walk spread. Try: 100% load and wait; then switch to "intervene".

worst queue seen
42
time above limit
6.9%
share of all path-periods
avg excursion above limit
20 periods
once out of control, it stays there
paths above limit at end
17%
  • takeawayQueues are the hidden inventory of product development and the root of most waste. Count them at every hand-off; they cost cycle time, risk, overhead, quality and motivation.
  • takeawayQueue size rises as 1/(1−ρ) and in proportion to variability. Pick utilization with a U-curve of capacity cost vs cost of delay; the higher the cost of delay, the further below 100% it sits.
  • takeawayManage the queue itself: watch it on a CFD, forecast with Little's Law, set limits, and intervene quickly when a random walk carries it past them. Use pooled queues and WSJF sequencing.

All 16 principles of managing queues

book chapter 3
  1. Q1
    The Principle of Invisible Inventory

    Product development inventory is information, so it is invisible both physically and on the balance sheet.

    A factory sees its work-in-process as piles on the floor and dollars on the books; a product team's queue is specs waiting for review, branches waiting for QA, and tickets in a backlog. Because nobody trips over it, nobody manages it. Make it visible: count the items waiting at every hand-off.

    ↑ see it in the visualization
  2. Q2
    The Principle of Queueing Waste

    Queues are the root cause of most of the economic waste in product development.

    Every item waiting in a queue adds cycle time, and with it more risk (the market and technology drift while it waits), more variability, more overhead to track and re-plan it, lower quality (feedback arrives late), and less motivation (no urgency for work that will just wait downstream).

    ↑ see it in the visualization
  3. Q3
    The Principle of Queueing Capacity Utilization

    Queue size grows explosively, not linearly, as capacity utilization approaches 100%.

    For an M/M/1 queue the number of items in the system is ρ/(1−ρ): going from 80% to 90% utilization more than doubles it (4 → 9), and 95% doubles it again (19). A team planned to 100% loading has, in theory, an infinite queue.

    ↑ see it in the visualization
  4. Q4
    The Principle of High-Queue States

    Most of a queue's damage comes from rare high-queue states, not from typical ones.

    Queue size follows a geometric distribution: long queues are improbable, but each one delays many items at once, so the low-probability tail carries a large share of the total delay. Watch for, and react to, those states rather than to the average.

    ↑ see it in the visualization
  5. Q5
    The Principle of Queueing Variability

    Variability in arrivals and in service times increases queue size roughly linearly.

    Kingman's approximation multiplies the M/M/1 queue by (Ca² + Cs²)/2: halving the variability of task durations (e.g. M/M/1 → M/D/1) halves the queue. Useful, but utilization is the bigger lever because it acts exponentially.

    ↑ see it in the visualization
  6. Q6
    The Principle of Variability Amplification

    At high utilization, small changes in load produce large swings in queue size and cycle time.

    The slope of the queueing curve, dLq/dρ, rises steeply near 100%. At 95% loading a 1-point change in load moves the queue by several items; at 70% it barely moves. Highly loaded processes amplify the variability fed into them.

    ↑ see it in the visualization
  7. Q7
    The Principle of Queueing Structure

    Serve pooled demand with reliable, high-capacity servers.

    One shared queue feeding several engineers beats a separate queue per engineer, because no one idles while another's line grows and one long job cannot block everyone behind it. A single fast server is even faster, but becomes a single point of failure.

    ↑ see it in the visualization
  8. Q8
    The Principle of Linked Queues

    Adjacent queues see either the arrival variability or the service variability of the upstream process, depending on how loaded it is.

    A lightly loaded upstream stage passes its arrival pattern straight through; a heavily loaded one releases work at the rhythm of its own service times. Look at the whole chain: smoothing a high-variability upstream step can shrink the queue at a downstream bottleneck.

    ↑ see it in the visualization
  9. Q9
    The Principle of Queue Size Optimization

    The right queue size is an economic trade-off between the cost of capacity and the cost of delay.

    More capacity costs money but cuts queues; less capacity saves money but delays everything. Add the two costs and pick the utilization at the bottom of the U-curve. The higher the cost of delay, the lower the economic utilization.

    ↑ see it in the visualization
  10. Q10
    The Principle of Queueing Discipline

    The cost of a queue depends on the order in which its jobs are served.

    When jobs differ in cost of delay and duration, first-in-first-out is rarely optimal; serving the highest cost of delay per unit of capacity first (WSJF) minimizes total delay cost. Sequencing matters most when queues are large; making queues small is better still.

    ↑ see it in the visualization
  11. Q11
    The Cumulative Flow Principle

    Use cumulative flow diagrams to monitor queues.

    Plot cumulative arrivals and cumulative departures over time: the vertical gap is the current queue, the horizontal gap is the time an item spends in it, and the slopes are demand and throughput. Emerging queues show up as a widening gap long before deadlines slip.

    ↑ see it in the visualization
  12. Q12
    Little's Formula

    Average wait time equals average queue size divided by average processing rate.

    Little's Law (W = L / λ) holds for any stable queue regardless of distributions. If a test team finishes 10 builds a week and 40 are waiting, a new build waits about four weeks; you can forecast cycle time from a queue count.

    ↑ see it in the visualization
  13. Q13
    The First Queue Size Control Principle

    Don't control capacity utilization; control queue size.

    Utilization is hard to measure and, near 100%, tiny errors in it mean huge differences in queues. Queue size is easy to count, and it is what actually causes delay, so set limits on it and act when they are exceeded.

    ↑ see it in the visualization
  14. Q14
    The Second Queue Size Control Principle

    Don't control cycle time; control queue size.

    Cycle time is a lagging indicator: you only learn it when items finish, long after the queue built up. Queue size is a leading indicator that moves the moment arrivals outpace capacity, so it lets you intervene earlier.

    ↑ see it in the visualization
  15. Q15
    The Diffusion Principle

    Over time, queues randomly drift into seriously out-of-control states and can stay there for long periods.

    A queue is the running sum of random differences between arrivals and departures, a random walk whose spread grows with the square root of time. Even with balanced average load, some paths wander far from zero and take a long time to come back.

    ↑ see it in the visualization
  16. Q16
    The Intervention Principle

    Randomness won't reliably fix a queue that randomness created; intervene quickly when it gets large.

    Because a random walk has no memory, a large queue is as likely to grow as to shrink. Set a queue limit and, when it is hit, act: add capacity, shed or block low-value demand, or purge work. Fast, small interventions keep queues bounded.

    ↑ see it in the visualization