Skip to content

Commit e66941e

Browse files
committed
docs: cover flow control default in sizing, architecture, and API docs
- operations.md: flow control queues buffer request bodies in EPP memory under saturation, bounded by per-band maxRequests/maxBytes; note that queues, fairness, and the saturation view are per replica in Active-Active mode. - architecture.md: note the flowControl gate is on by default and how to disable it. - apix: the FeatureGates doc claimed omitted gates are always disabled; gates carry per-gate defaults and support the name=false syntax. - metrics.md: request_processing_duration_seconds note updated for default-on. Signed-off-by: Luke Van Drie <lukevandrie@google.com>
1 parent c2328a1 commit e66941e

5 files changed

Lines changed: 30 additions & 11 deletions

File tree

apix/config/v1alpha1/endpointpickerconfig_types.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,9 @@ type EndpointPickerConfig struct {
3434
metav1.TypeMeta `json:",inline"`
3535

3636
// +optional
37-
// FeatureGates is a set of flags that enable various experimental features with the EPP.
38-
// If omitted none of these experimental features will be enabled.
37+
// FeatureGates is a set of flags that toggle optional EPP features. Each entry is a gate name,
38+
// optionally suffixed with "=true" or "=false" (a bare name means "=true"). Gates carry
39+
// per-gate defaults that apply when omitted; some (such as "flowControl") default to enabled.
3940
FeatureGates FeatureGates `json:"featureGates,omitempty"`
4041

4142
// +required
@@ -186,7 +187,8 @@ func (sp SchedulingPlugin) String() string {
186187
return "{" + strings.Join(parts, ", ") + "}"
187188
}
188189

189-
// FeatureGates is a set of flags that enable various experimental features with the EPP
190+
// FeatureGates is a set of flags that toggle optional EPP features ("name", "name=true", or
191+
// "name=false"); omitted gates use their registered defaults.
190192
type FeatureGates []string
191193

192194
func (fg FeatureGates) String() string {

docs/architecture.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,8 @@ RequestHandler:
195195
- When no parsers are configured, `openai-parser`, `anthropic-parser`, and `vllmhttp-parser` are used.
196196

197197
FlowControl:
198+
- The flow control admission layer itself is on by default (the `flowControl` feature gate);
199+
disable it with `featureGates: ["flowControl=false"]`.
198200
- `fcfs-ordering-policy`, `global-strict-fairness-policy`, and `static-usage-limit-policy` are configured when absent.
199201
- `utilization-detector` is configured as the saturation detector when none is set.
200202

docs/metrics.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ Unlabelled.
116116

117117
| Name | Type | Notes |
118118
|---|---|---|
119-
| `request_processing_duration_seconds` | Histogram | Time from request receipt until the request body has been handled. Includes admission control, so under the flow control feature gate this covers queue wait; `flow_control_request_queue_duration_seconds` separates it out. |
119+
| `request_processing_duration_seconds` | Histogram | Time from request receipt until the request body has been handled. Includes admission control, so with flow control on (the default) this covers queue wait; `flow_control_request_queue_duration_seconds` separates it out. |
120120
| `response_processing_duration_seconds` | Histogram | Sum of the per-chunk handler slices for a streamed response, so model-server generation time between chunks is excluded. For a non-streaming response, the interval from response headers to completion. |
121121

122122
### Plugin, info, and model rewrite

docs/operations.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ The EPP acts as the routing intelligence engine. Its resource usage scales prima
1919
#### Memory Allocation
2020
- **Base Memory**: EPP memory usage is relatively low and stable with small output token requests, but scales with the number of concurrent inflight requests.
2121
- **Inflight Requests Impact**: Memory usage increases with the number of concurrent inflight requests and the output (decode) token length.
22+
- **Flow Control Queues**: With flow control enabled (the default), requests that cannot dispatch
23+
under saturation are buffered in EPP memory, including their request bodies. The buffered volume
24+
is bounded per priority band by `flowControl` `maxRequests` (default 5000) and `maxBytes`
25+
(default 1G); budget for the sum of the per-band `maxBytes` limits of the priority levels your
26+
traffic actually uses, on top of the inflight-request sizing above. Lower these limits (or set a
27+
shorter `defaultRequestTTL`) to trade queueing for earlier shedding.
2228
- **Sizing Guidelines**:
2329
- For a request rate of 50 to 100 requests/second with 1k output tokens, EPP requires between **4 GiB and 6 GiB** of memory.
2430
- For workloads with longer output lengths (such as 5k output tokens), memory usage can reach **20+ GiB** due to the accumulation of state for concurrent inflight requests.
@@ -37,6 +43,10 @@ The EPP's scaling behavior and effectiveness are highly dependent on the configu
3743
| 3 | 2.7x |
3844
| 4 | 3.5x |
3945

46+
- **Note (Flow Control)**: Flow control state (queues, fairness accounting, and the saturation
47+
view) is per replica and not shared. In Active-Active mode, priority and fairness are enforced
48+
only within each replica's share of the traffic, and per-band capacity limits apply per
49+
replica, so the fleet-wide queued volume scales with the replica count.
4050
- **Warning (Prefix Routing)**: **Active-Active mode should be avoided when using approximate prefix routing.** Because EPP replicas do not share prefix state, each replica only has visibility into the prefix state of the requests it has individually handled. This partition of state significantly degrades prefix cache hit rates, making prefix caching highly inefficient.
4151
- For more technical details and context on EPP replica state sync and scaling limitations, see [Issue #1290](https://github.com/llm-d/llm-d-router/issues/1290).
4252

pkg/epp/flowcontrol/README.md

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,12 @@ high load.
3232

3333
### Enabling, disabling, and tuning
3434

35-
Flow control is enabled by default via the `flowControl` feature gate. With it on, requests queue
36-
under saturation and are admitted by priority instead of being rejected outright; sheddable
37-
(negative-priority) requests buffer until TTL or capacity limits are hit rather than shedding
38-
immediately on saturation. To restore the legacy saturation-only admission behavior, opt out in the
39-
EPP config:
35+
Flow control is enabled by default via the `flowControl` feature gate. With it on, saturation no
36+
longer pushes excess requests into each model server's local queue: they wait in the EPP and
37+
dispatch by priority as capacity frees, with queue wait bounded by a TTL. Sheddable
38+
(negative-priority) requests buffer under the same TTL and capacity rules instead of being
39+
rejected immediately on saturation. To restore the legacy saturation-only admission behavior, opt
40+
out in the EPP config:
4041

4142
```yaml
4243
featureGates: ["flowControl=false"]
@@ -46,8 +47,12 @@ Setting a `flowControl:` config section while the gate is disabled logs a warnin
4647
except `saturationDetector` (which the legacy admission path also uses) is ignored.
4748

4849
Operationally, dispatch decisions depend on fresh endpoint metrics: saturation detection reads the
49-
scraped model-server metrics, so a broken or stale scrape path degrades or halts dispatch. Keep
50-
metrics scrape health monitored when running with flow control on.
50+
model-server metrics that the EPP's own data layer scrapes from pods (this is independent of
51+
cluster monitoring such as Prometheus). Endpoints whose metrics are older than the detector's
52+
`metricsStalenessThreshold` count as fully saturated, so if the EPP loses its scrape path to all
53+
pods (network policy, metrics port change, a starved refresh loop), dispatch halts and queued
54+
requests eventually shed at their TTL. Keep the refresh interval comfortably inside the staleness
55+
threshold and monitor scrape health when running with flow control on.
5156

5257
Tuning knobs, all under the `flowControl:` config section:
5358

0 commit comments

Comments
 (0)