docs(guide): multi-tenant quota, priority & saturation (Pub/Sub or Redis SortedSet) - #285
Closed
shimib wants to merge 17 commits into
Closed
docs(guide): multi-tenant quota, priority & saturation (Pub/Sub or Redis SortedSet)#285shimib wants to merge 17 commits into
shimib wants to merge 17 commits into
Conversation
A runnable guide under docs/guides/multitenant-pubsub for running the async processor over GCP Pub/Sub with three teams: per-team quota (redis-quota gate keyed on a `team` message attribute), priority under saturation (per-team prometheus-query gates over vllm:num_requests_running), and two interchangeable observability backends — GCP Cloud Monitoring (GMP + query frontend) or a self-hosted Prometheus + Grafana stack (the chart's bundled PodMonitor / PrometheusRule / Grafana dashboard). Includes values overlays (quota-only, GMP saturation, Prometheus), redis / GMP / Prometheus manifests, a Cloud Monitoring dashboard, and GCP provisioning scripts. Requests are published via gcloud (the message contract is documented); no bundled publisher. All environment-specific values are placeholders (PROJECT_ID / NAMESPACE / IGW_HOST / model). Signed-off-by: Shimi Bandiel <shimib@google.com>
Add an animated SVG/HTML architecture diagram (diagram/architecture.html) and a rendered GIF embedded at the top of the guide README. The loop shows per-team message flow through the quota + saturation gates and the priority-under- saturation story (batch gate closes + backlog grows while premium keeps flowing). capture.sh regenerates the GIF headlessly via Chrome + ffmpeg. Signed-off-by: Shimi Bandiel <shimib@google.com>
Bright arrowed connectors between stages, flow dots rendered beneath the boxes so they ride exactly on the wires, and a calmer 20s loop. Regenerated GIF. Signed-off-by: Shimi Bandiel <shimib@google.com>
Slower dot flow, explicit Redis->gate quota wires (every connection now visible), flat background + deterministic capture for a clean jitter-free GIF. Signed-off-by: Shimi Bandiel <shimib@google.com>
Signed-off-by: Shimi Bandiel <shimib@google.com>
Adopt the two-level gate model: per-team redis-quota stays a QUEUE gate (admission/nack); the saturation priority moves to a POOL-level wait-on-refuse(prometheus-query) gate on each worker pool, so under saturation a team's workers park in-memory (ActionWait) instead of nacking (no broker backlog churn). README documents queue vs pool gates. Pool gates require the binary from llm-d#276 (pin an image that includes it; v0.7.1 predates it and ignores pool gate_type). Signed-off-by: Shimi Bandiel <shimib@google.com>
…pool saturation) Queue gate (quota/nack) between sub and pool; pool gate (saturation) after the pool with WAIT/park under load (batch parks in-memory, premium keeps flowing). Capture fix: state toggles use fill-opacity so headless screenshots render them. Signed-off-by: Shimi Bandiel <shimib@google.com>
Cloud Monitoring dashboard gains panels for async_dispatch_budget (gate openness per team), async_gate_decisions_total (by reason / team+reason), and worker utilization (inflight / pool_worker_limit). README notes they require an image newer than v0.7.2. Signed-off-by: Shimi Bandiel <shimib@google.com>
Incorporate all merged PRs since the branch was last updated, including the integration-test hang fix (llm-d#296) that was causing the pre-commit job to time out. Signed-off-by: Shimi Bandiel <shimib@google.com>
8 tasks
Note the status_code/error_code/error_message result schema so team consumers of results-sub can branch on HTTP vs non-HTTP outcomes. Signed-off-by: Shimi Bandiel <shimib@google.com>
…ackends Rename docs/guides/multitenant-pubsub -> multitenant and retitle to "Multi-tenant quota, priority & saturation". The scenario (per-team quota + priority + saturation) is queue-agnostic, so present the message queue as a pluggable backend fully supported on both Redis SortedSet (portable, featured first) and GCP Pub/Sub. - values overlays split into values/redis/ and values/pubsub/; new Redis SortedSet overlays (quota-only, saturation-prometheus) mirroring the Pub/Sub ones via redis.queuesConfig. - README rewritten scenario-first with a 'Choose your queue backend' section, per-backend publish helpers (ZADD envelope vs gcloud), results/backlog, and observability (self-hosted Prometheus for either; GMP for Pub/Sub on GKE). - Redis manifest now backs both the queues and quota counters (redis-quota service -> redis); gate addresses updated. - diagram/scripts framed as the Pub/Sub example / Pub/Sub-only. Verified all four AP overlays render and lint with helm template/lint. Signed-off-by: Shimi Bandiel <shimib@google.com>
Pick up llm-d#294 (tier-priority merge policy + requestMergePolicyConfig chart support). Signed-off-by: Shimi Bandiel <shimib@google.com>
…x tier) Rework the multi-tenant guide's priority model to use the tier-priority merge policy merged in llm-d#294: - All three teams feed ONE shared pool; each team queue carries a tier label (premium=interactive, standard=async, batch=batch). - redis-quota gate switched to classifying mode: within quota -> reserved, over quota -> overflow (dispatched, not nacked) — the per-team reserved lane. - ap.requestMergePolicyConfig: tier-priority — dispatches the 6 (classification x tier) lanes in strict order (all reserved before any overflow; tier-ordered within each) and stamps x-gateway-priority. - Saturation: one shared-pool wait-on-refuse(prometheus-query) gate; merge policy drains highest lanes first as capacity frees. - README: reworked What-it-shows table + lane table, Scenarios A/B (reserved vs overflow) and C (shared-pool saturation), quota/observability notes; diagram note updated. All 5 redis/pubsub overlays render + helm lint clean. Merged upstream/main (llm-d#294) to pick up the chart's requestMergePolicyConfig. Signed-off-by: Shimi Bandiel <shimib@google.com>
shimib
marked this pull request as ready for review
July 9, 2026 22:49
shimib
requested review from
RishabhSaini,
ahg-g,
evacchi and
jtechapps
as code owners
July 9, 2026 22:49
shimib
marked this pull request as draft
July 9, 2026 23:03
Add the model dimension: 2 models = 2 worker pools (model-a/model-b), 6 queues (team × model). Each model pool has its own saturation gate scoped to its InferencePool, its own tier-priority lane ordering, and per-(team,model) reserved quotas (redis-quota classifying, per-model prefix quota:a:/quota:b:). Showcases model isolation + reserved/overflow + tier priority together. - 5 redis/pubsub overlays reworked to 6 queues / 2 pools with per-model prefixes, result lists, tier labels, and per-pool saturation queries (POOL_A/POOL_B). - README rewritten for the 3 dimensions: topology, publish helper (team+model), scenarios (reserved/overflow+tier within a model; model isolation; per-model saturation), 2-InferencePool prereq, per-model counters. - gcp-setup/teardown create the 6 (team × model) topics/subscriptions. Tested: helm template + lint on all 5 overlays; a miniredis + fake-Prometheus + mock-gateway data-plane harness confirming per-model saturation isolation (model-a parks while model-b flows, then drains). Animation update follows. Signed-off-by: Shimi Bandiel <shimib@google.com>
Rework architecture.html into two model bands (model-a / model-b), each with its three team/tier lanes → reserved/overflow quota gate → tier-priority merge → its pool → per-model saturation gate → its own vLLM. The loop shows model isolation: model A saturates (pool gate WAIT, parks in-memory, red meter) while model B keeps flowing (OPEN, green). Regenerated architecture.gif/.mp4 via capture.sh (canvas 1300×900; window size updated to match). Signed-off-by: Shimi Bandiel <shimib@google.com>
Member
Author
|
relocating to llm-d/llm-d guides |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A runnable guide (
docs/guides/multitenant/) for the async processor showcasing team × tier × model multi-tenancy, with the message queue as a pluggable backend (Redis SortedSet or GCP Pub/Sub) and two observability options (self-hosted Prometheus/Grafana or GCP Cloud Monitoring).The three dimensions
model-a/model-b); 6 queues (team × model). The publisher setspayload.model; one gateway routes to twoInferencePools. Each pool has its own workers and its own saturation gate scoped to its model'sinference_pool, so a hot model can't starve a cold one.redis-quotain classifying mode (per-model prefixquota:a:/quota:b:): within quota →reserved, over →overflow(dispatched, not nacked).tierlabel; the tier-priority merge policy (Add tier-priority merge policy and gate + refactor merge policies #294) runs per pool, dispatching the 6(classification, tier)lanes in strict order (all reserved before any overflow) and stampingx-gateway-priority.Contents
values/redis/+values/pubsub/overlays (quota-only + saturation): 6 queues → 2 pools, per-model prefixes/result lists, tier labels, per-model saturation gates (POOL_A/POOL_B), tier-priority merge policy.publish <team> <a|b>, scenarios (A reserved/overflow+tier within a model; B overflow deprioritization + model isolation; C per-model saturation back-off), 2-InferencePool prereq.manifests/redis.yaml, GCP scripts (create the 6 team×model topics), observability manifests + Cloud Monitoring dashboard.diagram/architecture.html+ regeneratedarchitecture.gif): two model bands; model A saturates and parks while model B keeps flowing.How was this tested?
helm template+helm linton all 5 overlays (2 pools, 6 queues, per-model prefixes, per-model saturation scoping, merge policy).capture.sh(chrome + ffmpeg) and visually verified.Release note