docs: add QuotaPolicy capability guide#1947
Conversation
|
Related Documentation 9 document(s) may need updating based on files changed in this PR: Envoy's Space index
|
39cd2e2 to
d717bc6
Compare
JAORMX
left a comment
There was a problem hiding this comment.
Nice work documenting QuotaPolicy — the structure follows existing capability guides well and the progressive examples are clear. A few accuracy issues against the Go types that should be addressed.
|
|
||
| ```yaml | ||
| serviceQuota: |
There was a problem hiding this comment.
The variable list here is incomplete. Per shared_types.go, the CEL environment exposes 8 variables, not 3:
| Variable | Type | Description |
|---|---|---|
input_tokens |
uint | Input tokens |
cached_input_tokens |
uint | Cached read input tokens |
cache_creation_input_tokens |
uint | Cache creation input tokens |
output_tokens |
uint | Output tokens |
total_tokens |
uint | Total tokens (the default cost) |
reasoning_tokens |
uint | Reasoning tokens |
model |
string | Model name from request |
backend |
string | Backend as "name.namespace" |
total_tokens, reasoning_tokens, model, backend, and cache_creation_input_tokens are all missing.
| ```yaml | ||
| apiVersion: aigateway.envoyproxy.io/v1alpha1 | ||
| kind: QuotaPolicy | ||
| metadata: | ||
| name: my-quota-policy | ||
| spec: | ||
| targetRefs: | ||
| - group: aigateway.envoyproxy.io | ||
| kind: AIServiceBackend | ||
| name: my-backend | ||
| # Quota applied across all models and all clients. | ||
| serviceQuota: | ||
| quota: | ||
| limit: 100000 # Maximum tokens allowed in the window. | ||
| duration: "1h" # Sliding window duration. | ||
| ``` | ||
|
|
There was a problem hiding this comment.
Worth noting explicitly that serviceQuota only supports a flat limit + duration. Bucket modes, bucket rules, and client selectors are not available at the service-wide level — those are only on perModelQuotas (the Go types are ServiceQuotaDefinition vs QuotaDefinition).
Without this callout, a reader may try to add bucketRules or mode under serviceQuota and be confused when validation fails.
Suggestion — add a line like:
For bucket modes, client selectors, and per-tenant rules, use
perModelQuotasinstead.
| # Quota Policy | ||
|
|
||
| QuotaPolicy enables token-based quota management for AI inference services in Envoy AI Gateway. | ||
| When a service's quota is exceeded, requests are rejected with a `429` status code. If the |
There was a problem hiding this comment.
This feature requires the same infrastructure as usage-based rate limiting (Redis + Envoy Gateway rate limit service). A prerequisites section should be added, similar to the one in usage-based-ratelimiting.md (lines 50-58). Something like:
:::tip Prerequisites
Quota enforcement requires the same components as usage-based rate limiting:
1. **Redis Deployment**: A Redis instance for storing quota counters.
2. **Envoy Gateway Configuration**: Envoy Gateway must be configured at installation time to enable rate limiting and point to your Redis instance. See [Envoy Gateway Installation Guide](../../getting-started/prerequisites.md#additional-features-rate-limiting-inferencepool-etc)
:::
| This is useful for multi-tenant deployments where each tenant needs its own token budget. | ||
|
|
||
| ```yaml | ||
| perModelQuotas: | ||
| - modelName: gpt-4 | ||
| quota: | ||
| mode: Exclusive | ||
| defaultBucket: | ||
| limit: 10000 # Fallback quota for unmatched tenants. | ||
| duration: "1h" |
There was a problem hiding this comment.
The examples only show header-based client selectors, but the underlying RateLimitSelectCondition from Envoy Gateway also supports sourceCIDR, queryParams, path, and method matching. Worth mentioning these exist, or at minimum linking to the Envoy Gateway rate limit API reference so users know about the full set of selector options.
| backend whose quota has not been exhausted. | ||
|
|
||
| :::note | ||
| QuotaPolicy manages **total consumption budgets** (e.g., 100 000 tokens per hour). This is distinct |
There was a problem hiding this comment.
Nit: 100 000 uses a space as thousands separator. The YAML examples use 100000. Consider normalizing to 100,000 or 100000 for consistency.
Document the QuotaPolicy CRD, corrected against the current implementation: per-model token quotas as the primary mechanism, the full CEL cost-expression variable set, Shared-only bucket mode, the valid duration enum (1s/1m/1h/1d), client-selector conditions, shadow mode, prerequisites, and a service-wide quota section noting it is not yet enforced on the data plane. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Erica Hughberg <erica.sundberg.90@gmail.com>
4af8c72 to
df58593
Compare
…licy guide Failover on quota exhaustion and the backend-wide serviceQuota field are not yet enforced (failover awaits an unpublished Envoy release per envoyproxy#2261; serviceQuota enforcement is a known API TODO per envoyproxy#2249). Remove the failover claims entirely, and replace the Service-Wide Quota how-to and example with a short "not yet available" note. The guide now documents only what currently works, with a footgun warning for the exposed-but-inert field. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Erica Hughberg <erica.sundberg.90@gmail.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1947 +/- ##
=======================================
Coverage 84.69% 84.69%
=======================================
Files 144 144
Lines 21248 21248
=======================================
Hits 17997 17997
Misses 2166 2166
Partials 1085 1085 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
… scope The cost-expression examples used uint*int and uint*double arithmetic (e.g. "output_tokens * 6", "cached_input_tokens * 0.1"), which CEL rejects since the token variables are unsigned integers — the controller would skip the expression and silently stop enforcing that model's quota. Use unsigned literals and integer division (6u, / 10u), and document that fractional weights require an explicit uint(double(...)) cast. Also correct the clientSelectors note: QuotaPolicy only honors the headers matcher; sourceCIDR/methods/path/queryParams are accepted by the embedded EG type but not applied to quota buckets. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Erica Hughberg <erica.sundberg.90@gmail.com>
envoyproxy#2265 corrected the ServiceQuotaDefinition cost-expression example to valid CEL but left the identical QuotaDefinition (per-model) example unchanged. It still used "input_tokens + cached_input_tokens * 0.1 + output_tokens * 6", which multiplies uint token variables by int/double literals — CEL has no such overload, so llmcostcel.NewProgram rejects it. The controller then logs and skips the expression, silently leaving that model's quota unenforced. Match the already-fixed sibling field: "input_tokens + cached_input_tokens + output_tokens". Regenerates api.mdx and the CRD schema. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Erica Hughberg <erica.sundberg.90@gmail.com>
Co-authored-by: Aaron Choo <achoo30@bloomberg.net> Signed-off-by: Erica Hughberg <erica.sundberg.90@gmail.com>
Co-authored-by: Aaron Choo <achoo30@bloomberg.net> Signed-off-by: Erica Hughberg <erica.sundberg.90@gmail.com>
Co-authored-by: Aaron Choo <achoo30@bloomberg.net> Signed-off-by: Erica Hughberg <erica.sundberg.90@gmail.com>
Signed-off-by: Aaron Choo <achoo30@bloomberg.net>
|
/retest |
…y#1947 After envoyproxy#1947 merged, sync the new QuotaPolicy capability guide and related docs into the version-1.0 snapshot so the 1.0 docs match the latest: capabilities/traffic/quota-policy.md (new) plus updates to capabilities/index.md, capabilities/traffic/index.md, usage-based-ratelimiting.md, and api/api.mdx. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Erica Hughberg <erica.sundberg.90@gmail.com>
**Description** v1.0 GA documentation for the docs site. This is the project's first GA / major-version release, so the release notes are written as a special milestone edition rather than a normal incremental delta. What's included: - **Release notes (special GA edition).** `site/src/data/releases/v1.0.json` and `site/src/pages/release-notes/v1.0.mdx`. On top of the standard sections it adds GA-specific ones: a "What 1.0 Means" intro, an API-stability commitment callout, a "Road to 1.0" journey grid, and a Support & Compatibility Policy section. The framing is that v1.0 ratifies the existing `v1beta1` control-plane API as stable under SemVer — no apiVersion change and no resource migration, so upgrading from v0.7 is a drop-in. - **Versioned 1.0 docs.** The docs are snapshotted as `versioned_docs/version-1.0` and set as the default/latest version (`versions.json` + `docusaurus.config.ts`), including the QuotaPolicy capability guide from #1947. - **Plain-markdown release body** in `release-notes/v1.0.0.md` for the GitHub release. - **Announcement blog post** under `site/blog/2026/`, with a GA announcement/OG image and credited to all nine maintainers via the Docusaurus authors mechanism. - **Wiring**: v1.0 added to the release-notes index (featured) and the v0.7 to v1.0 navigation link. Dependency versions are sourced from `go.mod` and `.envoy-version`: Go 1.26.4, Envoy Gateway v1.8.1, Envoy 1.38.1, Gateway API v1.5.1, Gateway API Inference Extension v1.0.2, MCP Go SDK v1.6.1. AI assistance: this documentation was prepared with the help of Claude Code (Claude Opus 4.8) and reviewed before submission. **Related Issues/PRs (if applicable)** Related: #1947 (QuotaPolicy capability guide), #2270 (v1beta1 stable declaration + compatibility row). **Special notes for reviewers (if applicable)** The release notes, index cards, and blog are dated June 23, 2026 — please confirm this matches the actual v1.0.0 tag date at the cut and adjust if needed. This is intended to land as part of, or immediately before, the v1.0.0 release. --------- Signed-off-by: Erica Hughberg <erica.sundberg.90@gmail.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Description
Adds comprehensive documentation for the QuotaPolicy CRD, which was fully implemented
but had no user-facing documentation. Covers service-wide quotas, per-model quotas,
CEL cost expressions, Exclusive vs Shared bucket modes, client-selector based bucket rules,
shadow mode, and duration format. Follows the structure of existing traffic capability guides.
Distinguishes QuotaPolicy (total consumption budgets) from rate limiting (request velocity)
to help adopters choose the right mechanism.
Related Issues/PRs (if applicable)
Related #1571
Special notes for reviewers (if applicable)
All field definitions and semantics sourced from
api/v1alpha1/quota_policy.goGoDoc comments.Includes complete, copy-pasteable YAML examples for every configuration option.