Tenant budgets: coordinate rate, bursts, and in-flight work
Prevent replicated limiters and premature cancellation accounting from multiplying a tenant’s allowed load.
On this page
The question for today
What you’ll understand
- Calculate the aggregate envelope created by independent local buckets.
- Separate arrival-rate limits from in-flight concurrency bounds.
- Preserve trusted tenant attribution across admission, retries, and cancellation.
Three perfectly functioning local rate limiters can collectively admit three times the intended tenant budget. A separate concurrency counter can also look healthy while canceled requests continue executing on accelerators after their permits were returned. Tenant isolation needs an accounting design across replicas and actual work lifetimes. Envoy 1.31 documents complementary local and global rate-limiting mechanisms; the examples here examine general budget arithmetic rather than claim that a particular distributed limiter or accelerator cancellation protocol has been implemented.
Bind the budget to authenticated cost
Derive the tenant key from a trusted identity mapping, and carry it through asynchronous queues and retries. A user-controlled key allows identity rotation to evade a budget. Decide what is being charged: raw requests, input tokens, output tokens, bytes, accelerator milliseconds, or a conservative work estimate. A single short embedding and a long generation are not equal physical demands simply because both are HTTP requests. If the eventual cost is unknown at admission, reserve a bounded estimate and settle against actual consumption without allowing unbounded speculative work.
Charge retries and fan-out according to the resource obligation, not just the first public request. A gateway can admit one request that launches many retrieval calls or model attempts. If those downstream operations bypass the tenant budget, the upstream limiter measures an incomplete work path. Document who owns the reservation and when it is released or adjusted. Include denied work, estimation errors, and settlement failures in observability so that an attractive admitted-request counter cannot hide a growing pool of uncharged execution.
Global intent needs explicit coordination or partitioning
Giving every replica the full global rate and burst multiplies the allowance. One design uses a common decision service; another partitions the global budget into bounded local allocations. Leased allocations can reduce coordination frequency, but their ownership, expiry, replacement, and failover must prevent duplicate spend. A replacement replica must not reuse capacity that an old owner can still consume. Epochs or fencing can help enforce an ownership protocol, but naming a lease alone does not prove it. Define the failure policy when the coordination service is unavailable.
Static partitioning has a clear sum bound but can waste capacity when demand is uneven: one replica exhausts its share while another’s share sits idle. More dynamic borrowing can improve utilization at the cost of a more complex correctness argument. A local limiter can still protect a process from bursts before a global decision, as Envoy’s architecture describes. The two layers answer different questions. Test skewed routing, replica churn, partial coordinator failure, retries, and recovery rather than validate only the balanced all-replicas-healthy case.
Release concurrency when the charged work ends
Rate limits constrain admitted work over time; concurrency limits constrain simultaneously charged work. A slow downstream can create many in-flight operations even with a modest arrival rate. Cancellation is especially subtle: returning an HTTP error does not necessarily stop already launched GPU kernels or remote calls. Keep the relevant execution reservation until completion or a verified cancellation boundary, and distinguish a waiting-client permit from a physical-work permit. Otherwise clients can repeatedly cancel and relaunch while the reported concurrency remains low and real resource use grows.
Use separate fixed-rate queue runs as an overload analogy. Reset, explicitly set arrival two and service three, predict drainage from four initial items, then Play or Step. For a second run Reset and explicitly set arrival four and service three before predicting growth. Rate edits retain elapsed time and recompute the initial-value formula, rather than preserving a live backlog. The model has no token buckets, distributed leases, request costs, cancellation, or in-flight identities. Those accounting invariants require trace-based and failure-injection tests in the actual limiter.
Work it through
Partition one global budget instead of copying it
A hypothetical tenant should receive a sustained rate of 100 cost units per second and a burst of 50 units across three frontends. Compare copying that full budget to every frontend with one static partition.
Three independent full buckets collectively permit a refill of 300 units per second and an initial burst of 150 units. Each local bucket can be correct while the aggregate violates the intended tenant envelope.
One static partition assigns refill rates 33, 33, and 34 units per second and bursts 16, 17, and 17 units. The sums are 100 and 50, so the aggregate envelope respects the intended arithmetic if ownership and enforcement are correct.
Routing all demand to the first frontend can still reject work while the others have unused allocations. Moving their shares requires a protocol that prevents old and new owners spending the same budget. Static arithmetic does not by itself solve failover or make the policy work-conserving.
Partitioning preserves the intended sum under its assumptions; copying the full budget multiplies it. Coordination and skew determine the operational tradeoff.
The living notebook
Explore the model
Interactive lab · queue
Mean load imbalance does not implement a tenant limiter
Run Reset → set BOTH rates → predict → Play/Step independently for (λ,μ)=(2,3) and (4,3), each beginning from four abstract items. No tenant keys, local buckets, global checks, or cancellation accounting are simulated.
- Fluid backlog
- 4
- Net rate · λ − μ
- −1 /s
- M/M/1 mean residence
- 1 s
Fluid backlog starts at 4 and follows max(0, 4 + (λ − μ)t). The separate M/M/1 residence-time formula assumes Poisson arrivals, exponential service and λ < μ. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.
Look forA stable average is a planning condition; tenant budgets still require precise ownership and work-lifetime invariants.
Pause & reason
Check your understanding
Your turn
Try it yourself
A stable service completes 40 jobs per second with mean in-system residence of 0.2 seconds. Calculate mean in-system work. Does a concurrency cap of ten imply a 50-job-per-second rate limit or a deadline guarantee?
Take a moment to make a prediction or work it out on paper. Open a hint when you need one.
Give me a hint
Use Little’s law only for the long-run means, then distinguish a count ceiling from time and burst behavior.
Compare with the solution
The mean in-system work is 40×0.2=8 jobs under consistent stable-system accounting. A cap of ten does not itself impose a fixed 50-job-per-second rate: service times and admission patterns can vary, and bursts are a separate property. It also does not guarantee deadlines or bound continued execution after an incorrectly accounted cancellation. Define which work holds each permit, enforce tenant attribution, and test the actual completion and failure boundaries instead of treating the mean as a safety proof.
Keep the idea
Take it with you
- Sum every replica’s rate and burst allocation when checking a global tenant envelope.
- Coordinate budget ownership across skew, failover, and stale owners.
- Rate and concurrency limits protect different dimensions of actual work.
Read further
Original sources and deeper explanations to follow at your own pace.
Optional progress, saved in this browser when available. Revisit any lesson at any time.
Lesson not marked complete.