The material
Solving the identity for the letter you do not know
The three rearrangements, the unit trap in the middle of them, and the thread-count question they settle.
Definition · The three formsWith L the mean number in flight, λ the arrival rate and W the mean time in system: L = λW sizes the concurrency, λ = L/W gives the throughput a fixed concurrency supports, and W = L/λ gives the time in system implied by the other two. They are one equation rearranged, in the sense of Algebra's literal-equations-and-formulas.
The only difficulty is units. λ is per second and W is usually quoted in milliseconds, so the product needs one conversion — and skipping it produces an answer a thousand times too large, which is large enough to be noticed and small enough to be believed once someone has typed it into a configuration file.
λ = 500 / s W = 40 ms = 0.04 s
L = λW = 500 × 0.04 = 20 connections in flight
wrong: 500 × 40 = 20 000 per-second times milliseconds
the other direction
λ = N/W = 20 / 0.04 = 500 / s the ceiling that pool implies
Example · What a slower database does to a fixed poolThe pool of 20 above supports 500 a second at 40 ms. If the database slows to 80 ms, the same pool supports 20/0.08 = 250 a second. Holding 500 a second through it now needs 500 × 0.08 = 40 connections. Nothing about the traffic changed.
Threads, cores, and work that waits
A thread that is waiting on a network call is not using a core. Sizing a thread pool by core count is right for work that is CPU-bound and wrong for work that is not, and the identity says by how much: a service taking 200 requests a second, each spending 250 ms mostly waiting on a dependency, has 200 × 0.25 = 50 requests in flight. Eight cores is the wrong number to compare that with; 50 is the concurrency the work has, and the question is only whether the runtime can hold 50 waiting things cheaply.
This is also the honest way to read a “max connections” limit on a database. It is not a popularity cap; it is a W-dependent throughput cap, and the number it implies changes every time the query mix changes.
- Unknown L: you have a target rate and a measured latency, and you want a pool size.
- Unknown λ: you have a fixed pool and a measured latency, and you want the ceiling it imposes.
- Unknown W: you have a pool running at its ceiling, and you want the latency that implies — the answer the dashboard should agree with.
One warning before the lab. Sizing a pool at exactly L sizes it at the mean, and the mean is not the peak: arrivals bunch, and a pool sized at the mean is a queue in front of a queue. How much headroom that argues for is what the rest of this course prices, and the answer is a function of how close to its ceiling you are willing to run.