06

Controlling flow under uncertainty

WIP constraints cap the queues. This chapter covers the next set of controls. Keep occupancy below the point where the system congests. Run on a regular cadence so variance cannot pile up. Synchronize adjacent work so finished items do not sit idle. Sequence jobs by cost of delay divided by duration, not by arrival order. Route work through a flexible network and bind it to a resource as late as possible. Each of these tools is shown below as a model you can run.

Congestion: throughput is speed × density

F1F2
On a highway, speed falls as more cars crowd in. Throughput is their product, so it rises, peaks at half the jam density, and then falls. Past the peak, each extra car lowers output. That is congestion collapse. A test lab, a review queue or an overloaded team behaves the same way: past a certain occupancy, more work in the system means less work out. The fix is to regulate occupancy (ramp metering, a WIP cap) and keep the system on the left side of the curve.

Half a kilometer of one lane

23 cars · 63 km/h · 2,813 cars/h pass a point

Throughput = speed × density

throughput (cars/h)speed (km/h, scaled ×30)
congested: more cars → less flow01k2k3k050100density (cars/km)cars per hourpeak throughput2,813/h
Throughput
2,813/h
94% of peak
Forecast: 10 km trip
10 min
vs 6 min free-flow
Add 10% more cars
+3.4%
change in throughput
Speed
63 km/h

Try: push demand past 60 cars/km in open access and watch the “add 10%” stat turn negative. Then switch on ramp metering at ~55: throughput stays near peak and the excess waits harmlessly at the ramp.

Make congestion visible, then price it

F3F4
Demand peaks twice a day and exceeds capacity for a few hours. A fluid queue model shows the wait each arrival faces. That forecast is what you should publish, because a flow-time forecast is what people act on. A peak-hour price moves the flexible part of demand into the shoulders, where capacity is idle.

Demand over a day vs capacity

demand, no pricedemand with peak price
05001k1.5k0h5h10h15h20hhour of dayrequests / hourcapacity 1000/h

Visible congestion: forecast wait if you arrive at…

no pricewith peak price
01020300h5h10h15h20harrival timeminutes in queue
Worst forecast wait
4 min
4 min without price
Total queue time
97 req·h
97 without price
Queue time removed
0%
Demand shifted
0.0%
same total work, moved to off-peak

Try: raise the price from $0 to $5. Moving a small share of work out of the rush hours removes most of the queue time, because queue time grows nonlinearly with load. The right-hand curve is the forecast you would publish (F3) so requesters can decide for themselves.

Cadence stops variance from accumulating

F5F6
Forty projects each slip a random amount every week. Left alone, the slips add up like a random walk: the spread grows as σ√t. With a regular resynchronization point, each cycle starts clean. This works only if each cycle has a capacity margin to absorb that cycle’s noise. Without the margin, lateness carries over and the cadence holds only on paper.

No resynchronization: slips accumulate

-2002001020304050weekdays behind plan

Resync every 2 weeks

-2002001020304050weekdays behind plan
RMS slip at week 52
10.5 d
theory σ√52 = 10.8 d
…with cadence
1.6 d
Runs >5 d late at end
33%
no resync
…with cadence
3%
worst point 8.7 d

Try: set the margin to 0. Lateness carries over every cycle and the cadence no longer bounds anything (F6). Give each cycle a margin of about σ and the deviation resets every cycle (F5).

On-demand meetings vs a standing cadence

F7F8F9
Questions that need several people come up at random. An on-demand meeting has to wait for a day when everyone is free, and setting it up costs time. A standing slot, like a bus that leaves every N minutes, caps the wait at one interval and costs nothing to convene. Because it is cheap, it can run often with small batches.

Wait per question over 120 working days

cadence capacity 2.5/d vs demand 1.5/d · margin ok
● on-demand meeting (find a day all 5 are free)● standing meeting every 2 d
051015050100day the question came updays until answered
On demand
Mean wait
4.3 d
95th pct wait
11.3 d
Max wait
12.8 d
Questions / meeting
7.4
24 meetings
Scheduling overhead
40 h
emails, calendar hunts
Cadenced
Mean wait
1.1 d
95th pct wait
1.9 d
Max wait
3.2 d
Questions / meeting
3.0
60 meetings
Scheduling overhead
0 h
emails, calendar hunts

Try: raise “people needed” to 7. On-demand waits balloon because the chance that everyone is free on a day is 0.7n, while the standing slot never waits more than its interval. Then drop the slot capacity below demand: the cadence loses its margin and its waits stop being predictable.

Synchronize adjacent processes

F10F11F12F13F14
Upstream finishes a batch every few days and downstream picks up whatever is waiting on its own cycle. When cycles and phases match, finished work barely waits. When they do not, an inventory builds between two stages that both have enough capacity. Nested cadences only line up when one is a whole-number multiple of the other.

Handoffs: upstream completions → downstream pickups

upstream finishes a batchdownstream pulls everything waiting0d10d20d30d40d50d60d

Finished work waiting between the stages

024680204060dayunits in queueavg 2.1
Avg wait at handoff
2.26 d
Max wait
3.96 d
Avg queue
2.1 units
= arrival rate × avg wait
Cadences
drifting
pattern repeats only every 12 d

Try: “Synchronized” puts the pickup just after upstream finishes, so work barely waits. “Synced, no margin” uses the same cycles but picks up before the latest upstream finish, so jittered batches miss and wait a whole cycle (F10). “Non-harmonic” shows irregular waits that no offset can fix (F14).

Multiproject synchronization (F11). If five projects each need a prototype build, aligning them to one monthly build slot pays the setup cost once instead of five times, without making any project wait more than a month. A cadence gives the same scale economies as a large batch.
Cross-functional synchronization (F12). A design review with hardware, firmware, test and manufacturing present at once settles a trade-off in one sitting. The same decision passed around in sequence takes one queue per function and several loops.

Sequencing: who goes first?

F15F16F17F18F19F20
One team, several waiting jobs. Each job has a duration and a cost of delay (CoD) per week. The total delay cost of a schedule is Σ CoD × finish time. Ranking by CD3 = CoD ÷ duration (weighted shortest job first) minimizes it on a single resource. Edit the jobs and see which order wins.

Jobs waiting for one team

jobweeksCoD $k/wkCD3
APlatform migration1.00
BCheckout bug4.00
CEnterprise SSO5.00
DAnalytics export1.00
EPricing page1.00

Schedules (Gantt) and the delay cost each one pays

FIFO$251k delay costABCDEShortest job first$197k delay costBEDCAHigh cost of delay first$176k delay costCABDEWSJF$158k delay costCBADERound-robin$279k delay costABCDEACDACAAA012345678910111213
weeks → · grey slivers are context-switch time

Total cost of delay = Σ CoD × finish week

FIFO
$251k
+59%
Shortest job first
$197k
+25%
High cost of delay first
$176k
+11%
WSJF
$158k
+0%
Round-robin
$279k
+76%
WSJF delay cost
$158k
Smith's rule: optimal on one resource
FIFO pays
1.59×
$93k more than WSJF

Try: “Equal cost of delay” makes SJF tie WSJF (F15); “Equal durations” makes HDCF tie WSJF (F16). Switch to “durations unknown” and make job A 15 weeks long: the sorted policies can no longer see it coming, and round-robin with a cheap switch limits the damage (F19). Raise the switch cost to see why preemption only pays when switching is cheap (F20).

Priorities are local (F18). CD3 ranks the jobs waiting at this queue right now. A project labeled “priority 1” can rightly wait behind a short, urgent job at the test lab. One global ranking applied at every queue gets many of those calls wrong.
Preempt rarely (F20). Interrupting work pays only when the newcomer’s CD3 is much higher and the switch is cheap. Once you include setup and context-switch cost, which the slider models, frequent preemption usually costs more than it saves.

Routing work through a network

F21F22F23F24F25F26F27F28
Three people, three types of work, one of which is surging. You choose how much cross-training exists and when a job is bound to a person: at arrival (blind, or looking at the queues) or late, from a shared queue when someone frees up. Each cell is a discrete-event simulation of the same arrival stream.

Who can do what

work typespeopleX · 38%1X expertY · 31%2Y expertZ · 31%3Z expert

Solid: specialty. Dashed: cross-trained, works at 80% speed. Expert 1 alone faces 91% load from X.

Mean cycle time (× one job's service time), 15,000 simulated jobs each

Bind at arrival, blindBind at arrival, see queuesLate binding (shared queue)
Specialists only
8.6
p90 22.2
8.6
p90 22.2
8.6
p90 22.2
Chained cross-training
15.1
p90 36.4
4.1
p90 8.8
2.9
p90 6.2
Fully flexible
25.7
p90 59.1
4.3
p90 9.4
2.7
p90 5.7
Specialists, fixed route
8.6
every job waits for its expert
Chained cross-training, blind
15.1
Chained cross-training, visible queues
4.1
Chained cross-training, late binding
2.9
2.9× faster than specialists

Try: raise the share of type X until expert 1 is past 100% load. Specialists go unstable; one dashed link per person (chain) keeps everything flowing, and late binding beats binding at arrival even with the same people (F25, F26). Lower the off-specialty speed to see the cost of flexibility.

Tailored and flexible routing (F22, F23). Not every job needs every step, and the cheapest path changes as queues move. Choose the route per job at run time, like a packet router, not from a fixed process map.
Alternate routes and transparency (F24, F27). The dashed links are alternate routes. “See queues” is local transparency: routing to the shortest visible queue beats routing blind. Late binding with work matching (F21) does better still, because a freed specialist takes the job that fits it best.
Preplanned flexibility (F28). The chained cross-training in this model takes months to build. You cannot create it during the surge. Pay for it in advance, and keep it in use so it still works when you need it.

Centralize resources and condition flow into bottlenecks

F29F30
Two last corrections. First, pooling demand onto a shared set of resources smooths it, so a central pool reaches the same cycle time at much higher utilization (exact M/M/c vs M/M/1 math). Second, queue time at a bottleneck scales with the variability of what arrives, so smooth the flow before it reaches the bottleneck.

F29 · one shared pool vs dedicated resources

4 dedicated queues (M/M/1 each)one pool of 4 (M/M/4)
0510152020%40%60%80%utilizationcycle time ÷ service time
Dedicated
5.0×
Pooled
1.7×
Pooling gain
2.9×
same people, same load

Try: at 85% utilization with 4 resources, the pool cuts cycle time by about 3×. Add allocation delay to see when central control becomes the bottleneck itself.

F30 · smooth arrivals before the bottleneck

raw arrivalsconditioned arrivals
0102020%40%60%80%bottleneck utilizationqueue time ÷ service time
Queue, raw
7.8×
Queue, conditioned
1.8×
4.2× smaller
Same queue at
96.0%
utilization, if conditioned

Kingman: Wq ≈ ((ca² + cs²)/2) · ρ/(1−ρ) · ts. Arrival variability multiplies the bottleneck’s queue, so pay to smooth it upstream where capacity is cheap (release work at a steady rate, split big batches).

  • takeawayThroughput peaks at a moderate occupancy and collapses beyond it. Regulate what enters the system, and publish the forecast flow time so people can see the congestion.
  • takeawayCadence bounds variance, makes waits predictable and makes small batches cheap, provided each cycle has a capacity margin. Keep nested cadences harmonic and synchronize adjacent steps.
  • takeawaySequence by CD3 (cost of delay ÷ duration) at each queue. Use round-robin when sizes are unknown. Bind work to people late, through a flexible, visible network.

All 30 principles of controlling flow under uncertainty

book chapter 7
  1. F1
    The Principle of Congestion Collapse

    Above a certain load, output does not level off; it falls off a cliff.

    On a highway, a network or a busy engineering team, extra load past the peak makes everything slower, so less work leaves the system per hour. A test lab that accepts every request ends up with engineers chasing, re-queueing and re-running stale builds, and fewer tests finish per week than when it was less loaded.

    ↑ see it in the visualization
  2. F2
    The Peak Throughput Principle

    In systems that can congest, regulate occupancy so you stay at the load that gives the highest throughput.

    Throughput is speed × density, and speed drops as density rises, so throughput peaks at an intermediate occupancy. Ramp meters do this for freeways; a WIP limit on a review queue does it for a team: hold excess work outside, where it does no harm.

    ↑ see it in the visualization
  3. F3
    The Principle of Visible Congestion

    Make congestion visible by publishing a forecast of how long new work will take to get through.

    Drivers re-route when the sign says '35 min to downtown'; nobody re-routes on a raw queue count. Show requesters the expected flow time ('a new lab request today finishes in about 9 days') so they can choose to wait, reprioritize or go elsewhere.

    ↑ see it in the visualization
  4. F4
    The Principle of Congestion Pricing

    Charge more for capacity at congested times so that demand that can move, does.

    A modest price for peak capacity shifts flexible demand into the shoulders, where capacity sits idle. Internally this can be a priority surcharge on an expedite, or a budget charge for using the shared prototype shop during crunch weeks.

    ↑ see it in the visualization
  5. F5
    The Principle of Periodic Resynchronization

    Use a regular cadence to stop variance from piling up.

    Without resynchronization, schedule slips add up like a random walk and grow with the square root of time. Re-aligning plan and reality every period, as in a fixed-length sprint or release train, keeps deviations bounded to what happens within one cycle.

    ↑ see it in the visualization
  6. F6
    The Cadence Capacity Margin Principle

    A cadence only holds if there is enough spare capacity to absorb each cycle's variation.

    A bus can depart on time only if the schedule has slack for slow traffic. A two-week sprint loaded to 100% cannot absorb surprises, so lateness rolls into the next sprint and the cadence becomes fiction; plan sprints with a margin.

    ↑ see it in the visualization
  7. F7
    The Cadence Reliability Principle

    Use cadence to make waiting times predictable.

    If the architecture review happens every Tuesday, nobody waits more than a week, and everyone knows it. An on-demand review has no ceiling on wait: it depends on whether the reviewers' calendars line up.

    ↑ see it in the visualization
  8. F8
    The Cadence Batch Size Enabling Principle

    A regular cadence lowers transaction cost, which makes small batches economical.

    Pre-scheduled events cost almost nothing to convene, so you can hold them often and handle a few items each time. Weekly releases on a fixed train are cheaper per release than ad-hoc releases that must be negotiated, so batches shrink.

    ↑ see it in the visualization
  9. F9
    The Principle of Cadenced Meetings

    Hold frequent meetings on a predictable schedule instead of convening them on demand.

    A short daily or twice-weekly slot where the right people are already present removes the scheduling overhead and the multi-day lead time of finding a common free hour. Questions wait at most one interval.

    ↑ see it in the visualization
  10. F10
    The Synchronization Capacity Margin Principle

    Synchronization only works if each participant has enough capacity margin to show up on time.

    If the handoff is at 10:00 and upstream sometimes finishes at 10:15, those items miss the pickup and wait a full cycle. Leave enough margin (or offset the pickup) to cover upstream variation.

    ↑ see it in the visualization
  11. F11
    The Principle of Multiproject Synchronization

    Synchronize work from several projects to share fixed costs and gain scale.

    One combined design review, one shared prototype build or one test-lab slot that serves several projects at once spreads the fixed setup cost. Projects that align their milestones to a common cadence get these economies without large batches.

    ↑ see it in the visualization
  12. F12
    The Principle of Cross-Functional Synchronization

    Use synchronized events that bring every function together to make cross-functional trade-offs quickly.

    A trade-off between firmware, hardware and manufacturing is resolved in minutes when all three are in the same room at the same time, and in weeks when it is negotiated by sequential handoffs and email.

    ↑ see it in the visualization
  13. F13
    The Synchronization Queueing Principle

    Align the batch size and timing of adjacent processes to shrink the queue between them.

    If upstream finishes a batch just before downstream pulls one, work barely waits. Mismatched cycles or phases leave finished work idle in an inventory between the two stages, even when both have plenty of capacity.

    ↑ see it in the visualization
  14. F14
    The Harmonic Principle

    Make nested cadences whole-number multiples of each other.

    Daily stand-ups inside two-week sprints inside quarterly releases line up every time. A 3-day cycle feeding a 4-day cycle drifts in and out of phase, so waits are irregular and synchronization is lost.

    ↑ see it in the visualization
  15. F15
    The SJF Scheduling Principle

    When every job has the same cost of delay, do the shortest job first.

    Finishing short jobs first means fewer jobs sit waiting behind long ones, so the total delay paid is smallest. Quick bug fixes before a long refactor, if they are equally urgent.

    ↑ see it in the visualization
  16. F16
    The HDCF Scheduling Principle

    When every job takes the same time, do the job with the highest cost of delay first.

    With equal durations, the only lever is which delay cost you pay the longest; make the cheap-to-delay jobs wait. Among equally sized features, ship the one that unlocks the biggest customer first.

    ↑ see it in the visualization
  17. F17
    The WSJF Scheduling Principle

    When durations and costs of delay both vary, use weighted shortest job first: rank by cost of delay divided by duration.

    Cost of delay divided by duration (CD3) is the delay cost avoided per unit of scarce capacity. Sorting by it minimizes total delay cost on a single resource; SJF and HDCF are its special cases.

    ↑ see it in the visualization
  18. F18
    The Local Priority Principle

    Priorities are local: they belong to a queue at a moment, not to a project for all time.

    A 'priority 1 project' does not need to go first in every queue it touches; at a given resource, what matters is the CD3 of the waiting jobs right there. Global rankings applied everywhere make the wrong call at many queues.

    ↑ see it in the visualization
  19. F19
    The Round-Robin Principle

    When you cannot know how long tasks will take, share capacity in short time slices.

    Round-robin keeps one unexpectedly huge job from blocking all the short ones behind it: each job gets a quantum in turn, so short jobs finish early. Pick a quantum long enough that switching costs stay small.

    ↑ see it in the visualization
  20. F20
    The Preemption Principle

    Interrupt work in progress only when the cost of switching is low.

    Preempting makes sense when a new job's cost of delay is far higher and the switch is cheap. Every interruption costs setup and context, and frequent preemption can cost more than the delay it saves.

    ↑ see it in the visualization
  21. F21
    The Principle of Work Matching

    Use sequencing to match each job to the resource best suited for it.

    When a specialist frees up, pick the waiting job that benefits most from that specialist instead of the next in line. This only works if the decision is made when the resource frees up, not when the job arrives.

    ↑ see it in the visualization
  22. F22
    The Principle of Tailored Routing

    Choose and adjust the sequence of process steps to suit each job.

    A one-line config change should not travel the same 14-step path as a new subsystem. Let low-risk work skip steps that add no value for it and send high-risk work through extra checks.

    ↑ see it in the visualization
  23. F23
    The Principle of Flexible Routing

    Route each job through whatever path is currently the most economical.

    The best path changes as queues come and go. Like a router or a GPS, decide the route at run time from current congestion, not from a fixed plan made months ago.

    ↑ see it in the visualization
  24. F24
    The Principle of Alternate Routes

    Build and maintain alternate routes around points of congestion.

    A second qualified test vendor, a backup reviewer, or a simulation that can stand in for a hardware test: alternates absorb surges. They must be exercised regularly or they will not work when needed.

    ↑ see it in the visualization
  25. F25
    The Principle of Flexible Resources

    Use flexible, cross-trained resources to absorb variation.

    Even a little cross-training, such as each engineer able to cover one neighbor's area, captures most of the benefit of full flexibility because it links all the queues into one chain.

    ↑ see it in the visualization
  26. F26
    The Principle of Late Binding

    The later you commit a job to a specific resource, the smoother the flow.

    Assigning work to a person at arrival locks it into that person's queue even if someone else frees up first. Keep a shared queue and bind work only when a resource is actually free.

    ↑ see it in the visualization
  27. F27
    The Principle of Local Transparency

    Make tasks and resources reliably visible to adjacent processes.

    Flexible routing and late binding need to see where the queues are and who is free. A visible board of the next process's queue lets upstream route work to an idle path instead of a blind guess.

    ↑ see it in the visualization
  28. F28
    The Principle of Preplanned Flexibility

    If you need fast responses, plan and pay for flexibility before you need it.

    Cross-training, pre-qualified alternate suppliers and modular architectures take time to build. Flexibility bought in advance is cheap insurance; flexibility improvised in a crisis is slow and expensive.

    ↑ see it in the visualization
  29. F29
    The Principle of Resource Centralization

    Centralized resources, managed correctly, reduce queues.

    Pooling demand from many sources onto a shared pool of servers smooths variation, so a central pool needs less capacity for the same wait time than dedicated per-team resources. It fails only if central allocation becomes slow or bureaucratic.

    ↑ see it in the visualization
  30. F30
    The Principle of Flow Conditioning

    Reduce the variability of the flow before it reaches a bottleneck.

    Queue size at a bottleneck grows with the variability of arrivals into it. Smooth the arrivals upstream, where capacity is cheap, so the expensive bottleneck runs at high utilization without a large queue.

    ↑ see it in the visualization