← Workflows

阅读中文版本

Adaptive Concurrency Limit Workflow

Tune a concurrency limit adaptively from observed latency, using additive increase and multiplicative decrease to find the sweet spot without manual setting.

intermediate~40 minconcurrencyadaptiveperformance

Objective

Find the maximum concurrency that keeps latency under the SLO by adapting the limit from real-time measurements, not a static guess.

Environment

  • A service with a concurrency limiter and latency metrics
  • A load generator that can vary the offered concurrency
  • An SLO on p99 latency

Steps

1. Measure at current limit

Apply the current concurrency limit, run the load generator, and record the p99 latency and the throughput.

Expected state: A measurement pair of p99 latency and throughput at the current limit.

2. Adjust the limit

If latency is under the SLO, increase the limit additively; if over, decrease it multiplicatively to back off fast.

Expected state: A new limit that moves toward the sweet spot without overshooting.

3. Confirm convergence

Repeat the measure-adjust cycle until the limit stabilizes within a band for several rounds.

Expected state: The limit oscillates in a narrow band around the sweet spot, not a single value.

4. Lock and monitor

Pin the converged limit as the default and add a dashboard alert if latency crosses the SLO, so a regression triggers re-adaptation.

Expected state: The limit is set and the alert watches for drift.

Decision points

Additive increase step size?

  • Small (1) for stability
  • Large (10) for speed

Small for production, large for initial tuning.

Multiplicative decrease factor?

  • 0.5 for fast back-off
  • 0.9 for gentle back-off

0.5, because overshooting latency is worse than undershooting throughput.

Expected outcome

The concurrency limit converges to a value that maximizes throughput while keeping p99 latency under the SLO, and a dashboard alert catches regressions.

Verification

Run the load generator at the converged limit and confirm p99 latency is under the SLO across 1000 requests, and that the limit did not change in the last 5 rounds.

Cleanup

Keep the converged limit and the alert; remove the load-generator artifacts and record the converged value in the runbook.

Measure before you adjust

A concurrency limit that is too high degrades latency; one that is too low wastes capacity. The right limit is where throughput stops rising and latency starts rising, and that point shifts with the load and the downstream, so a static guess is wrong eventually.

loadtest --concurrency $LIMIT --duration 30s --metric p99

Additive increase, multiplicative decrease

When latency is under the SLO, increase the limit by a small additive step, because the sweet spot is nearby and a big jump overshoots. When latency is over the SLO, decrease the limit by a multiplicative factor, because a latency violation is urgent and a fast back-off recovers sooner.

if p99 < SLO: LIMIT=$((LIMIT + 1)); else LIMIT=$((LIMIT / 2)); fi

Confirm convergence

The limit does not converge to a single value; it oscillates in a band around the sweet spot. Confirm convergence by checking the limit stayed within a band for several rounds, then pin the midpoint as the default.

Verification

The converged limit keeps p99 latency under the SLO across 1000 requests, and the limit did not change in the last 5 rounds. The dashboard alert watches for latency regressions that would trigger re-adaptation.