Most concurrency bugs start with a guess. Someone sets a worker pool to 50, a connection pool to 20, or an agent tool to unlimited, and the number survives until an incident. The fix is not a bigger guess. It is to read the downstream service's own signals and derive the cap from them.
Three numbers matter, and you want all three from the same downstream:
- Service time, reported as a percentile rather than a mean.
- Error rate at a specific level of load.
- In-flight count or utilization at that same moment, so you can tell where the knee sits.
Percentiles are the only honest summary of a right-skewed distribution. Averages hide slow requests because a handful of outliers get diluted in the sum, and a service that averages 100 ms can still have a meaningful share of requests taking seconds (Redis on p95). A p95 of 200 ms means 1 in 20 requests took longer, which at production traffic is a lot of real users. For concurrency work, p95 is the workhorse: it describes the common slow path, usually a specific query, cache miss or lock, while p99 tends to catch GC pauses and cold starts (the percentiles guide).
One trap before you measure anything: you cannot average percentiles. Ten instances each reporting a p95 do not average into a valid fleet-wide p95. You need to merge the underlying histograms and then query the percentile (Redis, the percentiles guide). If your dashboard lets you average a p95 line over time or across hosts, it is already lying to you.



