Chapter 8. Managing mixed workloads with priority queuing
With flow control, you can offer different quality of service for latency-sensitive and throughput-sensitive workloads, or clients, on the same model servers without violating service-level agreements (SLAs), reducing capital expenses and maximizing accelerators return on investment.
flow control is a Technology Preview feature only. Technology Preview features are not supported with Red Hat production service level agreements (SLAs) and might not be functionally complete. Red Hat does not recommend using them in production. These features provide early access to upcoming product features, enabling customers to test functionality and provide feedback during the development process.
For more information about the support scope of Red Hat Technology Preview features, see Technology Preview Features Support Scope.
8.1. Flow Control and priority-based queuing Copy linkLink copied to clipboard!
Flow control is a pool defense mechanism in the Endpoint Picker (EPP) component of Distributed Inference with llm-d. It manages request queuing, prioritization, and fairness in a multi-tenant inference serving environment, which helps with consolidating latency-sensitive and throughput-sensitive workloads on a single cluster, reducing infrastructure costs while protecting critical service level objectives (SLOs).
Use flow control in the following scenarios:
- You run many tenant applications with different service level agreement (SLA) requirements on shared GPU infrastructure
- You need to guarantee latency for interactive workloads while maximizing GPU usage with batch jobs
- You want to merge separate Distributed Inference with llm-d deployments for different service tiers onto a single cluster
- You need to protect critical workloads from noisy neighbor effects
- You want to implement service tiering for multi-tenant LLM inference
If you only have a single workload type with uniform SLA requirements, flow control adds unnecessary complexity.
How Flow Control works
Flow control manages request queuing, prioritization, and fairness between the Inference Gateway and InferencePool backends.
When a request arrives:
The Gateway’s
AuthPolicyautomatically injects two headers based on authentication:-
x-gateway-inference-fairness-id- Groups requests from the same authentication source for fair queuing -
x-gateway-inference-objective- Determines request priority by matching anInferenceObjectiveresource
-
- The request enters a priority-aware queue in the Endpoint Picker and waits for dispatch.
The dispatch logic applies strict priority ordering:
- Higher-priority requests dispatch before lower-priority requests
-
Requests at the same priority level use fairness policies. The default
global-strict-fairness-policyis a greedy strategy that ignores tenant boundaries and offers no isolation. A single tenant in a priority can starve other tenants of the same priority. For equitable service distribution, configureround-robin-fairness-policy
A saturation check monitors queue depth and KV cache utilization on model servers:
- When pool saturation is detected (saturation >= 1), dispatch is halted for all priority bands
- All requests wait in their respective priority queues until capacity becomes available
- When capacity is available, the request proceeds to the Scheduling layer and routes to a specific model server.
Flow control queues requests when the InferencePool has no ready backends, hiding startup time from clients during scale-from-zero scenarios.
Key concepts
- Priority levels
Platform administrators create
InferenceObjectiveresources to define priority tiers. Higher integer values represent higher priority.Example tier structure:
Expand Tier Priority Value Use Case Critical
100
Interactive applications
Standard
0 (default)
Standard API calls
Best-Effort
-10
Batch workloads
- Authentication-based prioritization
The Gateway
AuthPolicyautomatically sets thex-gateway-inference-objectiveheader:- ServiceAccount tokens: Header is set to the ServiceAccount’s namespace
-
User tokens: Header is set to
authenticated Anonymous requests: Header is set to
unauthenticatedCreate
InferenceObjectiveresources with names matching these header values to assign priorities.
8.2. InferenceObjective custom resource reference Copy linkLink copied to clipboard!
The InferenceObjective Custom Resource defines priority values for inference requests in flow control. You create InferenceObjective resources to establish priority tiers for different workload classes.
apiVersion: inference.networking.x-k8s.io/v1alpha2
kind: InferenceObjective
metadata:
name: <service-account-namespace>
namespace: <llmisvc-namespace>
spec:
priority: 100 # Higher = higher priority
poolRef:
group: inference.networking.k8s.io
kind: InferencePool
name: <llmisvc-name>-inference-pool
| Field | Type | Required | Description | Valid Values |
|---|---|---|---|---|
|
| integer | No |
Priority value for requests matching this | Positive values (higher priority, example: 100), Zero (default priority), Negative values (lower priority, dispatched last, example: -10) |
|
| string | No |
API group for the InferencePool resource. If not specified, defaults to |
|
|
| string | No |
Resource kind. If not specified, defaults to |
|
|
| string | Yes |
Name of the InferencePool resource this | Name of your InferencePool resource |
8.3. Configure flow control for Distributed Inference with llm-d Copy linkLink copied to clipboard!
You can enable flow control in Distributed Inference with llm-d and create InferenceObjective resources to implement priority-based queuing for multitenant workloads. This procedure configures the flow control layer, defines priority tiers, and validates that priority queuing is working correctly.
Prerequisites
- Distributed Inference with llm-d is deployed with Inference Gateway and Endpoint Picker (EPP).
- You have enabled authentication and authorization for your LLM Inference Service. To do this, follow the steps for Enabling authentication and authorization for an LLM inference service
- You have cluster administrator access.
Procedure
Configure the Endpoint Picker to enable flow control and configure saturation detection. The
EndpointPickerConfigis embedded within theLLMInferenceServicecustom resource underspec.router.scheduler. Edit yourLLMInferenceServiceresource:$ oc edit llminferenceservice <llm-service-name> -n <namespace>Locate the
spec.router.schedulersection and add theflowControlfeature gate and configure thesaturationDetector:apiVersion: inference.networking.x-k8s.io/v1alpha1 kind: EndpointPickerConfig featureGates: - "flowControl" saturationDetector: queueDepthThreshold: 5 kvCacheUtilThreshold: 0.8 metricsStalenessThreshold: 200mswhere:
-
queueDepthThreshold: Specifies the queue depth threshold on model servers. A value of 5 (default) balances latency and throughput. Set to 1 for maximum fairness (forces all queuing into EPP priority-aware queues). Set to 1-2x max batch size for maximum throughput (allows model servers to form fuller batches). To decide your model server’s batch size for tuningqueueDepthThreshold, check the vLLM deployment’s--max-batch-total-tokensparameter or refer to yourLLMInferenceServiceconfiguration. If unsure, start with the default value of 5 and adjust based on observed latency and throughput metrics. -
kvCacheUtilThreshold: Specifies the KV cache utilization threshold (0.0 to 1.0). Default is 0.8. -
metricsStalenessThreshold: Specifies how long metrics can be stale before being considered invalid. Default is 200ms.
-
- Save and exit the editor.
Create an
InferenceObjectiveresource to define a priority tier:apiVersion: inference.networking.x-k8s.io/v1alpha2 kind: InferenceObjective metadata: name: <objective-name> namespace: <namespace> spec: priority: <priority-value> poolRef: group: inference.networking.k8s.io kind: InferencePool name: <inference-pool-name>where:
-
metadata.name- Specifies theInferenceObjectivename. -
metadata.namespace- Specifies the namespace where theInferencePoolis deployed. priority- Specifies the priority value. Higher integer values represent higher priority. Negative values designate lower-priority requests that are queued and dispatched last. Requests can be rejected when:- The priority band’s capacity is exhausted (HTTP 429)
- They time out (HTTP 503)
- The client disconnects abruptly (HTTP 503)
-
poolRef.name- Specifies the name of theInferencePoolresource this objective applies to.
-
Apply the
InferenceObjectiveresource:$ oc apply -f <inference-objective-file>.yamlOptional: Configure advanced flow control settings for priority bands.
After creating
InferenceObjectiveresources, you can customize flow control behavior by configuring priority band capacity, request timeouts, and fairness policies. Edit yourLLMInferenceServiceresource and add theflowControlconfiguration underspec.router.scheduler:apiVersion: inference.networking.x-k8s.io/v1alpha1 kind: EndpointPickerConfig featureGates: - "flowControl" flowControl: maxBytes: 1073741824 defaultRequestTTL: 1m priorityBands: - priority: 1 orderingPolicyRef: fcfs-ordering-policy fairnessPolicyRef: round-robin-fairness-policy - priority: 0 orderingPolicyRef: fcfs-ordering-policy fairnessPolicyRef: round-robin-fairness-policy - priority: -1 orderingPolicyRef: fcfs-ordering-policy fairnessPolicyRef: round-robin-fairness-policywhere:
-
maxBytes- Specifies the priority band’s capacity in bytes. When this limit is exceeded, requests receive HTTP 429 errors. Default is 1073741824 (1 GiB). -
defaultRequestTTL- Specifies the request timeout. Requests waiting longer than this duration receive HTTP 503 errors. Default is 1 minute. -
priorityBands[].priority- Specifies the priority value for this band. Must match the priority values defined in yourInferenceObjectiveresources. -
priorityBands[].orderingPolicyRef- Specifies the ordering policy. Default isfcfs-ordering-policy(first-come, first-served). -
priorityBands[].fairnessPolicyRef- Specifies the fairness policy. The defaultglobal-strict-fairness-policyoffers no tenant isolation and can result in starvation. For equitable service distribution across tenants, useround-robin-fairness-policy.
-
Verification
Send sustained traffic with varying request priorities using load testing tools.
Priority differentiation is active whenever there are multiple requests waiting in the queue. The saturation signal controls whether anything gets dispatched at all. Use load testing tools to send sustained traffic with varying request priorities, tenant fairness IDs, and concurrent request volumes.
Monitor flow control metrics in Prometheus:
-
inference_extension_flow_control_queue_size- Queue depth for requests waiting to dispatch -
inference_extension_flow_control_request_queue_duration_seconds- Time requests sit in the flow control queue
-
- If queue depth remains at 0, increase concurrency to create saturation conditions where priority differentiation occurs.
Additional resources
Additional resources