Flow control currently enforces binary backpressure: when the backend pool reaches 100% saturation, EPP stops dispatching and queues incoming requests.
To protect critical real-time latency SLOs under heavy load, we need a progressive holdback mechanism. This allows EPP to proactively gate/buffer lower-priority traffic (e.g., best-effort batch at 75% load, standard at 90% load) as pool saturation rises, thereby maintaining a reserve of available compute capacity to absorb sudden high-priority bursts.
Since priority levels are dynamically derived from InferenceObjective CRDs at runtime, hardcoded mappings are brittle. We will implement a parameter-driven priority-holdback-policy* plugin. This plugin will implement EPP's pluggable flowcontrol.UsageLimitPolicy` interface and support multiple gating algorithms to dynamically distribute admission ceilings across the $[0, 1]$ saturation range.
1. Pluggable Progressive Gating Strategies
The plugin will compute an admission ceiling $c_i \in [0.0, 1.0]$ for each active priority. In the EPP dispatchCycle, traffic is gated if the pool's current saturation exceeds the priority's ceiling ($S > c_i$).
The plugin may support the following gating strategies (seeking feedback here):
A. static
- Algorithm: Fixed, explicit mapping.
- Formula:
$$c_i = \begin{cases}
\text{StaticMap}[p_i] & \text{if } p_i \in \text{StaticMap} \
\text{DefaultStaticCeiling} & \text{otherwise}
\end{cases}$$
B. stepwise-spread
- Algorithm: Automatically divides the range between a configured
minCeiling ($c_{min}$) and maxCeiling ($c_{max}$) into equal steps based strictly on the number $N$ of currently active priorities, ignoring their absolute numerical difference.
- Formula (for index $i$ in sorted descending active priorities):
$$c_i = c_{max} - i \times \frac{c_{max} - c_{min}}{N - 1}$$
C. linear-proportional
- Algorithm: Scales ceilings linearly between $c_{min}$ and $c_{max}$ based on the numerical value of active priorities relative to the observed active range $[p_{min}, p_{max}]$.
- Formula:
$$r_i = \frac{p_i - p_{min}}{p_{max} - p_{min}}$$
$$c_i = c_{min} + r_i \times (c_{max} - c_{min})$$
D. sigmoid-smoothed
-
Algorithm: Maps priorities to ceilings along a normalized logistic sigmoid curve to create "soft floors" and "soft ceilings", grouping similar priorities together.
-
Formula:
$$\sigma(x) = \frac{1}{1 + e^{-k(x - x_0)}}$$
$$S_{norm}(x) = \frac{\sigma(x) - \sigma(0)}{\sigma(1) - \sigma(0)}$$
$$c_i = c_{min} + S_{norm}(x_i) \times (c_{max} - c_{min})$$
(Support mapping over either the absolute priority value domain or the relative index rank domain)
2. Safety Guarantees & Corner Cases
- Single Active Priority ($N = 1$): To respect flow control's work-conserving nature, if only a single priority level is active, EPP will bypass progressive holdback and assign it $c_{max}$ (usually
1.0), preventing artificial limits when the pool has spare capacity.
- Dynamic Priority Inversion Prevention: To guarantee that a higher priority is never gated before a lower priority (regardless of mathematical edge cases), the plugin will run a right-to-left monotonizing sweep over the calculated ceilings:
// Ensure ceilings[i] >= ceilings[i+1] (highest first)
for i := n - 2; i >= 0; i-- {
if ceilings[i] < ceilings[i+1] {
ceilings[i] = ceilings[i+1]
}
}
- Boot-Time Validation: The plugin factory will perform local priority-inversion validation on startup when using the
static mapping. EPP will fail to boot on invalid configurations.
3. Configuration Schema
The policy is configured inside the existing EPP plugins block and referenced inside flowControl:
apiVersion: inference.networking.x-k8s.io/v1alpha1
kind: EndpointPickerConfig
metadata:
name: default-config
featureGates:
- flowControl
plugins:
- type: priority-holdback-policy
name: dynamic-holdback
parameters:
strategy: "sigmoid-smoothed"
minCeiling: 0.6
maxCeiling: 1.0
sigmoidSteepness: 8.0
sigmoidMidpoint: 0.5
sigmoidDomain: "value"
flowControl:
usageLimitPolicyPluginRef: dynamic-holdback
Flow control currently enforces binary backpressure: when the backend pool reaches 100% saturation, EPP stops dispatching and queues incoming requests.
To protect critical real-time latency SLOs under heavy load, we need a progressive holdback mechanism. This allows EPP to proactively gate/buffer lower-priority traffic (e.g., best-effort batch at 75% load, standard at 90% load) as pool saturation rises, thereby maintaining a reserve of available compute capacity to absorb sudden high-priority bursts.
Since priority levels are dynamically derived from$[0, 1]$ saturation range.
InferenceObjectiveCRDs at runtime, hardcoded mappings are brittle. We will implement a parameter-drivenpriority-holdback-policy* plugin. This plugin will implement EPP's pluggableflowcontrol.UsageLimitPolicy` interface and support multiple gating algorithms to dynamically distribute admission ceilings across the1. Pluggable Progressive Gating Strategies
The plugin will compute an admission ceiling$c_i \in [0.0, 1.0]$ for each active priority. In the EPP $S > c_i$ ).
dispatchCycle, traffic is gated if the pool's current saturation exceeds the priority's ceiling (The plugin may support the following gating strategies (seeking feedback here):
A.
static$$c_i = \begin{cases}
\text{StaticMap}[p_i] & \text{if } p_i \in \text{StaticMap} \
\text{DefaultStaticCeiling} & \text{otherwise}
\end{cases}$$
B.
stepwise-spreadminCeiling(maxCeiling(C.
linear-proportionalD.
sigmoid-smoothed(Support mapping over either the absolute priority
valuedomain or the relative indexrankdomain)2. Safety Guarantees & Corner Cases
1.0), preventing artificial limits when the pool has spare capacity.staticmapping. EPP will fail to boot on invalid configurations.3. Configuration Schema
The policy is configured inside the existing EPP
pluginsblock and referenced insideflowControl: