AI Platform Tenant Quota Isolation: Constrain Requests, Tokens, Concurrency, and GPU Time Together
Single QPS rate limiting cannot stop long-context and batch tasks from squeezing inference pools. This article designs tiered quotas, atomic accounting, fair queuing, burst allowance, and failure degradation to protect multi-tenant AI platforms.
Key Points
- Topic Focus: AI、大模型、DevOps
- Suitable for: indie hackers, full-stack engineers, AI application developers
- Core value: quickly understand background, practical paths, common pitfalls, and engineering advice
In ordinary APIs, the cost difference between requests is limited, so limiting the number of requests per second per tenant is usually sufficient. AI inference is not like this: a request may only generate a dozen tokens, or it may carry an ultra-long context, stream output for minutes, and trigger multiple tool calls. If a platform only limits QPS, a small batch of long requests from a large customer can fill up GPU decode slots, and other tenants will queue even if they are not over quota. This is the classic noisy neighbor problem.
Tenant isolation must form a closed loop from identity, accounting, queuing, execution to observability. The tenant ID must be derived from a trusted authentication context and cannot accept self-reported values from the request body; project, environment, and user can serve as secondary dimensions, but ultimately all belong to a billable, auditable root tenant. When internal services call on behalf of users, the original tenant and delegated identity must be propagated, rather than everything falling under a single "platform service account" to bypass limits.
Quota is a resource vector
At least five types of quotas must be managed simultaneously: request rate prevents the control plane from being overwhelmed, input and output token budgets constrain inference cost, concurrent requests or active sequences protect real-time slots, queue length limits memory and wait time, and GPU seconds or total task cost controls long-term consumption. For Agents, you also need to limit the number of model calls, tool rounds, and cumulative tokens per run, to avoid loops that stay within each local limit while exhausting global resources.
Quotas are divided into long-term guarantees and short-term bursts. The token bucket allows trusted tenants to accumulate a small amount of burst normally, but the bucket capacity must be limited, and an entire month of unused quota cannot be released onto a shared cluster within a minute. Concurrency quotas usually should not accumulate. Different models have different resource costs, and you can use benchmarked "inference units" for pricing, but still display user-understandable tokens, concurrency, and amounts externally, to avoid black-box billing.
LLM Rate Limiting and Quota is suitable for defining product-tier quotas, and API Rate Limiting Strategies provides algorithmic foundations such as token buckets. The platform tier must also map quotas to real queues and GPU pools; otherwise, after the gateway returns "allowed", the scheduler may still let some tenant occupy resources indefinitely.
Reservation, settlement, and compensation must be atomic
Before streaming generation begins, you cannot know the exact output token count. You can first reserve quota based on input tokens and the request's maximum output cap; during generation, periodically settle actual usage, and release unused portions at the end. If the client cancels, the stop signal must be transmitted to the inference backend and billed according to the resources already consumed. Billing only when the response completes will let disconnected and timed-out requests consume GPU for free.
A distributed gateway needs shared and consistent quota state. Checks and deductions should be atomic operations carrying a globally unique request ID. Retrying the same ID returns the original reservation result and does not deduct again; timeout states enter pending reconciliation rather than defaulting to a rollback. The strategy when the accounting service is unavailable is differentiated by risk: free sandboxes can reject new requests, and critical paid tenants can use small local emergency quotas, but you must never fail-open indefinitely.
reserve(tenant, requestId, inputTokens, maxOutputTokens, modelClass)
-> reservationId, admittedUnits, expiresAt
settle(reservationId, actualInput, actualOutput, gpuMillis)
cancel(reservationId, consumedSoFar)
Reservation records should have a TTL, but before background cleanup, the execution status must be queried to prevent the quota from being incorrectly released while a long request is still running. Daily reconciliation compares gateway reservations, actual tokens from the model service, GPU metering, and billing events; when differences exceed a threshold, freeze auto-settlement and alert, instead of silently modifying the user balance.
Fair queuing cannot rely solely on FIFO
Global FIFO will let a large batch of tasks submitted by one tenant block everyone. A more reasonable approach is to maintain separate queues per tenant, and then use weighted fair scheduling or deficit round robin to take tasks from each active tenant in rotation. Weights represent the purchased guaranteed share, not unlimited priority; a single tenant is still subject to concurrency and total budget limits. Interactive, batch, and evaluation tasks should be divided into priority pools; batch tasks can utilize idle capacity, but yield resources when interactive traffic resumes.
Priority and preemption must be handled carefully. A long generation that has already started being preempted wastes GPU time and breaks user experience; prioritize scheduling at the queuing stage, or use execution methods that support state saving. High priority can only come from server-side policy, and cannot be upgraded by a client passing a header. Kubernetes ResourceQuota can isolate CPU, memory, and object counts at the namespace level, but cannot independently understand the tokens and KV Cache of each inference request, so application quotas and cluster resource quotas must coexist.
Isolate all shared state
Quotas do not replace data isolation. Cache keys, batch aggregation, observability labels, log sampling, model adapters, and object storage paths must all include verified tenant scopes. The context propagation principles in MCP Multi-Tenant Isolation equally apply to inference platforms: each hop in the backend receives trusted tenant context and rejects when missing, rather than falling back to a public tenant.
Especially check the semantic cache and dynamic batching. Requests from different tenants can be batched together at the GPU layer, but response mapping, cancellation signals, and metrics must be isolated per request; caches containing private data cannot hit across tenants. Tenant labels in platform metrics should use stable internal IDs or hashes, and control label cardinality; raw user identifiers do not enter the public monitoring system.
Degrade according to commitments when capacity is tight
When the cluster is saturated, first pause unguaranteed batch tasks, then limit bursts, and finally queue fairly according to tenant guaranteed shares. When returning 429 or an explicit resource-exhausted state, attach a reasonable retry time and request ID; do not let the SDK immediately retry without jitter to form a second wave of traffic. For mission-critical tasks, you can switch to an approved fallback pool, but still follow the same tenant quota, and cannot reset quota by switching models.
The dashboard simultaneously shows per-tenant admissions, rejections, queue times, active sequences, input/output tokens, GPU seconds, reservation and settlement differences, and shared pool SLOs. Platform operators need to view aggregated hotspots, while tenants can only see their own data. Capacity and cost attribution can be combined with Cloud Cost Optimization to match guaranteed shares with actually reserved resources.
During acceptance, simulate a single tenant burst, ultra-long output, client cancellation, gateway retry, accounting service interruption, queue worker restart, and shared pool capacity reduction. Confirm that other tenants' latency is still within target, that the same request is not double-deducted, that invalid reservations eventually converge, that batch tasks actually yield resources, and that no path can forge a tenant. True tenant isolation is not adding a rate limiting middleware to the API, but keeping identity, quotas, scheduling, state, and ledger within the same boundary even during failures.
Further Reading
Related
Related Content
Article
What Is Vibe Coding? Will It Change How Programmers Work?
Technical trends, engineering practices, and an indie developer perspective on Vibe Coding, AI, and independent development.
Article
From Copilot to Codex: AI Coding Tools Enter the Agent Era
Technical trends, engineering practices, and indie-developer perspectives around AI, AI Agents, and Vibe Coding.
Article
Core Architecture of AI Agents: Planning, Memory, Tools, and Execution
Technical trends, engineering practices, and independent developer perspectives around AI Agents and large language models.
Article
Complete Technology Stack Analysis for LLM Application Development
Covers tech trends, engineering practices, and indie developer perspectives around large models, RAG, and AI.