{"course":{"slug":"how-software-changed","title":"How Software Development Changed","url":"https://addaly.com/learn/how-software-changed","level":"intermediate","track":"work"},"lesson":{"slug":"queues-not-speeds","title":"Queues, not speeds","url":"https://addaly.com/learn/how-software-changed/queues-not-speeds","position":6,"of":87,"minutes":10,"answer":"Throughput is set by the slowest stage, waiting time explodes non-linearly as that stage approaches full utilisation, so a faster writing stage in front of a busy review stage lengthens delivery rather than shortening it.","keyIdea":"Throughput is set by the slowest stage, waiting time explodes non-linearly as that stage approaches full utilisation, so a faster writing stage in front of a busy review stage lengthens delivery rather than shortening it."},"body":{"format":"markdown","text":"## The arithmetic that decides whether faster writing helps\n\nDelivery is a pipeline of stages, and the throughput of a pipeline is set by its slowest stage. That is not a metaphor. It has arithmetic, the arithmetic is simple, and it predicts what most teams have observed since they adopted these tools: more activity, the same delivery.\n\nStart with Little's Law, which holds for any stable queue regardless of what it contains:\n\n```\nL = λ × W\n```\n\nWork in progress equals arrival rate times time in system. Rearranged, the version you will use daily is `W = L / λ`.\n\nA team merges 20 pull requests a week and has 25 open at any moment. Average time from open to merged is 25 / 20 = 1.25 weeks. Nobody needs a dashboard to compute that, and it is usually the first honest number a team has ever had about itself.\n\n## What happens when you double the input\n\nThe writing stage gets faster. Pull requests arrive at 40 a week instead of 20. Review capacity is unchanged, because reviewing is done by the same humans with the same days.\n\nIf review can service 20 a week, the queue does not settle at a longer wait. It grows without bound: 20 extra items each week, for ever, until something breaks: usually the review, which gets shallower until the arrival rate and the service rate match again. That is not a metaphor either. That is what a shallow review is: the system finding its equilibrium by lowering the service quality.\n\n## Utilisation is the number that surprises people\n\nEven below saturation, the wait time is not linear. For a single-server queue with ordinary variability in arrival and service times, average waiting time scales roughly with `ρ / (1 − ρ)`, where ρ is utilisation. In units of one service time, that gives:\n\n> Figure: What happens as a reviewer fills up. Line chart of average wait, in service times against reviewer utilisation, per cent: A single-server queue with ordinary variability (50, 1) (70, 2.3) (80, 4) (90, 9) (95, 19). A reviewer who goes from 80 per cent booked to 90 has not got 12 per cent busier. The queue in front of them roughly doubles, which is why everyone experiences it as a sudden collapse rather than a gradual slide.\n\n- 50% utilised: about 1 service time of waiting\n- 70%: about 2.3\n- 80%: about 4\n- 90%: about 9\n- 95%: about 19\n\nA reviewer who is 80% booked and becomes 90% booked has not got 12% busier. The queue in front of them has roughly doubled. This is why a team can add a modest amount of work and see review latency triple, and why everyone experiences it as a sudden collapse rather than a gradual slide.\n\nIt is also why slack is not waste. A reviewer with free hours is what keeps the pipeline's wait time small, and that free time will always look like the obvious thing to fill.\n\n## Find your constraint before you optimise anything\n\nTake the last thirty changes that reached production and record the timestamps at each stage. Most issue trackers and git hosts hold all of this already.\n\n1. Request understood → specification agreed\n2. Specification → first commit\n3. First commit → pull request opened\n4. Pull request opened → first substantive review comment\n5. First review → approved\n6. Approved → merged\n7. Merged → deployed\n8. Deployed → confirmed working\n\nTake the median of each. In most teams that have measured this, stages 4 and 7 dominate and stage 2 (the actual writing) is a small fraction of the total. That is the whole argument of this module in one table of your own numbers, and it is much more persuasive to a sceptical manager than anything in this course.\n\n## The Theory of Constraints move\n\nEliyahu Goldratt's sequence is worth memorising because it prevents the most common mistake:\n\n1. **Identify** the constraint.\n2. **Exploit** it: make sure the constraint never idles. If review is the constraint, a reviewer should never be waiting for context, a rebase, or a green build.\n3. **Subordinate** everything else to it. Other stages run at the constraint's pace, on purpose.\n4. **Elevate** it: add capacity. More reviewers, or better tooling for reviewers, or smaller changes so each review is cheaper.\n5. **Repeat**, because the constraint will move.\n\nStep 3 is the one people refuse. Deliberately not writing more code, because review cannot absorb it, feels like laziness and shows up badly in any activity metric. It is nonetheless the correct action, and refusing it is how a growing pile gets built.\n\n## The counterintuitive prescription\n\nIf review is your constraint, the correct response to a faster writing stage is to **lower work in progress**, not raise it.\n\nConcretely: cap open pull requests per person at two. When you hit the cap, you do not open a third: you go and review, or you go and help get one of yours merged. This looks like reducing output and it increases delivered throughput, because it moves effort to the constraint and shortens every queue in the system.\n\nOne more, cheaper still: shrink the unit of work. A queue's wait time depends on service time, and a 200-line change is reviewed properly in twenty minutes while a 2,000-line change is reviewed properly in nobody's afternoon. Halving diff size does more for lead time than any tool you can buy, and it is free."},"check":{"question":"A team's reviewers are about 85% utilised. Leadership adds two more engineers who write code but do not review, hoping to raise delivery. What does the queueing model predict?","options":[{"text":"Review utilisation rises towards saturation, wait times grow faster than the extra load suggests, and throughput stays flat.","correct":true},{"text":"Delivery rises by roughly the proportion of new writing capacity, because the pipeline is not yet saturated at 85%.","correct":false,"tempting":"Assumes throughput scales with the stage you added to, when throughput is set by the stage that was already nearest saturation."},{"text":"Delivery is unchanged, because the new engineers' output simply queues and nothing else in the system is affected.","correct":false,"tempting":"Half right on throughput but misses that a longer queue degrades the constraint itself: reviewers under a growing pile review less carefully."},{"text":"Delivery falls only if the new engineers write lower-quality code than the existing team, which is an onboarding problem rather than a queueing one.","correct":false,"tempting":"Attributes a structural effect to the quality of individuals, which predicts the problem disappears once they are experienced. It does not."}]},"prev":{"slug":"the-perception-gap","title":"Why it feels faster than it measures","url":"https://addaly.com/learn/how-software-changed/the-perception-gap"},"next":{"slug":"tasks-sorted-by-payoff","title":"Where the gain is large, small, and negative","url":"https://addaly.com/learn/how-software-changed/tasks-sorted-by-payoff"},"authorship":"Founder and series editor: Dr Mustafa Mun. Written by AI models to a written standard. Exam keys checked blind by a second model: 3,665 of 3,666 agreed. Academic review invited.","review":{"status":"Draft, open for academic review"},"cite":"Addaly (2026) 'Queues, not speeds', in How Software Development Changed. Edited by M. Mun. Addaly. Available at: https://addaly.com/learn/how-software-changed/queues-not-speeds (Accessed: 13 October 2026).","licence":{"name":"CC BY-NC-SA 4.0","url":"https://creativecommons.org/licenses/by-nc-sa/4.0/"},"reader":{"schema":1,"title":"Queues, not speeds","courseTitle":"How Software Development Changed","module":{"index":1,"slug":"where-the-cost-went","title":"Where the cost actually went"},"answer":null,"keyIdea":"Throughput is set by the slowest stage, waiting time explodes non-linearly as that stage approaches full utilisation, so a faster writing stage in front of a busy review stage lengthens delivery rather than shortening it.","hero":{"kind":"figure","figure":{"t":"figure","label":"Figure","figure":{"type":"line","title":"What happens as a reviewer fills up","series":[{"label":"A single-server queue with ordinary variability","points":[[50,1],[70,2.3],[80,4],[90,9],[95,19]]}],"xLabel":"reviewer utilisation, per cent","yLabel":"average wait, in service times","caption":"A reviewer who goes from 80 per cent booked to 90 has not got 12 per cent busier. The queue in front of them roughly doubles, which is why everyone experiences it as a sudden collapse rather than a gradual slide."},"alt":"Figure: What happens as a reviewer fills up. Line chart of average wait, in service times against reviewer utilisation, per cent: A single-server queue with ordinary variability (50, 1) (70, 2.3) (80, 4) (90, 9) (95, 19). A reviewer who goes from 80 per cent booked to 90 has not got 12 per cent busier. The queue in front of them roughly doubles, which is why everyone experiences it as a sudden collapse rather than a gradual slide."}},"blocks":[{"t":"h2","id":"the-arithmetic-that-decides-whether-faster-writing-helps","runs":[{"text":"The arithmetic that decides whether faster writing helps"}]},{"t":"p","runs":[{"text":"Delivery is a pipeline of stages, and the throughput of a pipeline is set by its slowest stage. That is not a metaphor. It has arithmetic, the arithmetic is simple, and it predicts what most teams have observed since they adopted these tools: more activity, the same delivery."}]},{"t":"p","runs":[{"text":"Start with Little’s Law, which holds for any stable queue regardless of what it contains:"}]},{"t":"code","lang":"","label":"Text","text":"L = λ × W"},{"t":"p","runs":[{"text":"Work in progress equals arrival rate times time in system. Rearranged, the version you will use daily is "},{"text":"W = L / λ","code":true},{"text":"."}]},{"t":"p","runs":[{"text":"A team merges 20 pull requests a week and has 25 open at any moment. Average time from open to merged is 25 / 20 = 1.25 weeks. Nobody needs a dashboard to compute that, and it is usually the first honest number a team has ever had about itself."}]},{"t":"h2","id":"what-happens-when-you-double-the-input","runs":[{"text":"What happens when you double the input"}]},{"t":"p","runs":[{"text":"The writing stage gets faster. Pull requests arrive at 40 a week instead of 20. Review capacity is unchanged, because reviewing is done by the same humans with the same days."}]},{"t":"p","runs":[{"text":"If review can service 20 a week, the queue does not settle at a longer wait. It grows without bound: 20 extra items each week, for ever, until something breaks: usually the review, which gets shallower until the arrival rate and the service rate match again. That is not a metaphor either. That is what a shallow review is: the system finding its equilibrium by lowering the service quality."}]},{"t":"h2","id":"utilisation-is-the-number-that-surprises-people","runs":[{"text":"Utilisation is the number that surprises people"}]},{"t":"p","runs":[{"text":"Even below saturation, the wait time is not linear. For a single-server queue with ordinary variability in arrival and service times, average waiting time scales roughly with "},{"text":"ρ / (1 − ρ)","code":true},{"text":", where ρ is utilisation. In units of one service time, that gives:"}]},{"t":"ul","items":[[{"text":"50% utilised: about 1 service time of waiting"}],[{"text":"70%: about 2.3"}],[{"text":"80%: about 4"}],[{"text":"90%: about 9"}],[{"text":"95%: about 19"}]]},{"t":"p","runs":[{"text":"A reviewer who is 80% booked and becomes 90% booked has not got 12% busier. The queue in front of them has roughly doubled. This is why a team can add a modest amount of work and see review latency triple, and why everyone experiences it as a sudden collapse rather than a gradual slide."}]},{"t":"p","runs":[{"text":"It is also why slack is not waste. A reviewer with free hours is what keeps the pipeline’s wait time small, and that free time will always look like the obvious thing to fill."}]},{"t":"h2","id":"find-your-constraint-before-you-optimise-anything","runs":[{"text":"Find your constraint before you optimise anything"}]},{"t":"p","runs":[{"text":"Take the last thirty changes that reached production and record the timestamps at each stage. Most issue trackers and git hosts hold all of this already."}]},{"t":"ol","start":1,"items":[[{"text":"Request understood → specification agreed"}],[{"text":"Specification → first commit"}],[{"text":"First commit → pull request opened"}],[{"text":"Pull request opened → first substantive review comment"}],[{"text":"First review → approved"}],[{"text":"Approved → merged"}],[{"text":"Merged → deployed"}],[{"text":"Deployed → confirmed working"}]]},{"t":"p","runs":[{"text":"Take the median of each. In most teams that have measured this, stages 4 and 7 dominate and stage 2 (the actual writing) is a small fraction of the total. That is the whole argument of this module in one table of your own numbers, and it is much more persuasive to a sceptical manager than anything in this course."}]},{"t":"h2","id":"the-theory-of-constraints-move","runs":[{"text":"The Theory of Constraints move"}]},{"t":"p","runs":[{"text":"Eliyahu Goldratt’s sequence is worth memorising because it prevents the most common mistake:"}]},{"t":"ol","start":1,"items":[[{"text":"Identify","b":true},{"text":" the constraint."}],[{"text":"Exploit","b":true},{"text":" it: make sure the constraint never idles. If review is the constraint, a reviewer should never be waiting for context, a rebase, or a green build."}],[{"text":"Subordinate","b":true},{"text":" everything else to it. Other stages run at the constraint’s pace, on purpose."}],[{"text":"Elevate","b":true},{"text":" it: add capacity. More reviewers, or better tooling for reviewers, or smaller changes so each review is cheaper."}],[{"text":"Repeat","b":true},{"text":", because the constraint will move."}]]},{"t":"p","runs":[{"text":"Step 3 is the one people refuse. Deliberately not writing more code, because review cannot absorb it, feels like laziness and shows up badly in any activity metric. It is nonetheless the correct action, and refusing it is how a growing pile gets built."}]},{"t":"h2","id":"the-counterintuitive-prescription","runs":[{"text":"The counterintuitive prescription"}]},{"t":"p","runs":[{"text":"If review is your constraint, the correct response to a faster writing stage is to "},{"text":"lower work in progress","b":true},{"text":", not raise it."}]},{"t":"p","runs":[{"text":"Concretely: cap open pull requests per person at two. When you hit the cap, you do not open a third: you go and review, or you go and help get one of yours merged. This looks like reducing output and it increases delivered throughput, because it moves effort to the constraint and shortens every queue in the system."}]},{"t":"p","runs":[{"text":"One more, cheaper still: shrink the unit of work. A queue’s wait time depends on service time, and a 200-line change is reviewed properly in twenty minutes while a 2,000-line change is reviewed properly in nobody’s afternoon. Halving diff size does more for lead time than any tool you can buy, and it is free."}]}],"check":{"question":[{"text":"A team’s reviewers are about 85% utilised. Leadership adds two more engineers who write code but do not review, hoping to raise delivery. What does the queueing model predict?"}],"options":[{"text":[{"text":"Review utilisation rises towards saturation, wait times grow faster than the extra load suggests, and throughput stays flat."}],"correct":true,"tempting":null},{"text":[{"text":"Delivery rises by roughly the proportion of new writing capacity, because the pipeline is not yet saturated at 85%."}],"correct":false,"tempting":[{"text":"Assumes throughput scales with the stage you added to, when throughput is set by the stage that was already nearest saturation."}]},{"text":[{"text":"Delivery is unchanged, because the new engineers’ output simply queues and nothing else in the system is affected."}],"correct":false,"tempting":[{"text":"Half right on throughput but misses that a longer queue degrades the constraint itself: reviewers under a growing pile review less carefully."}]},{"text":[{"text":"Delivery falls only if the new engineers write lower-quality code than the existing team, which is an onboarding problem rather than a queueing one."}],"correct":false,"tempting":[{"text":"Attributes a structural effect to the quality of individuals, which predicts the problem disappears once they are experienced. It does not."}]}],"order":[2,1,3,0],"why":null},"prev":{"slug":"the-perception-gap","title":"Why it feels faster than it measures","minutes":8},"next":{"slug":"tasks-sorted-by-payoff","title":"Where the gain is large, small, and negative","minutes":10}}}