Intelligent LLM Autoscaling with KEDA and vLLM on OpenShift: Scaling on KV-Cache Pressure and ITL Latency
Briefing Summary
In enterprise large language model (LLM) production deployments, infrastructure autoscaling presents a critical operational and financial dilemma: On one hand, over-provisioning high-end GPU nodes (NVIDIA H100/H200, B200, or L40S) leads to astronomical cloud costs during off-peak hours. On the other hand, under-provisioning leads to queue saturation, memory exhaustion, and unacceptable spikes in Time-To-First-Token (TTFT) and Inter-Token Latency (ITL) for interactive users and AI agents.
The traditional reaction of infrastructure teams is to configure a standard Kubernetes Horizontal Pod Autoscaler (HPA) based on CPU utilization, system RAM, or generic GPU memory. However, for modern continuous-batching inference engines like vLLM or TGI, this approach is fundamentally broken: VRAM is pre-allocated up to 90% at engine boot via PagedAttention, leaving external memory metrics flat, static, and completely blind to real workload demands.
Learn how to implement intelligent event-driven autoscaling using KEDA (Kubernetes Event-driven Autoscaling) on Red Hat OpenShift AI (RHOAI), driving the lifecycle of inference replicas directly from internal KV-Cache pressure and real-time request queue metrics.
1. Why Traditional Autoscaling Fails for LLMs
To understand why traditional autoscaling mechanisms fail on GenAI workloads, we must analyze the internal mechanics of modern inference engines:
┌─────────────────────────────────────────────────────────────────────────────┐
│ Why Standard HPA is Blind to LLMs │
├─────────────────────────────────────────────────────────────────────────────┤
│ 1. VRAM Memory : vLLM pre-allocates KV-Cache at boot (gpu_memory_util=0.90).│
│ => Kubernetes perceives 90% VRAM constantly (zero workload signal). │
│ │
│ 2. GPU Utilization (%) : Wildly oscillates between Prefill and Decode. │
│ => Causes rapid flapping, thrashing, and destructive pod termination. │
│ │
│ 3. HTTP Request Rate (RPS) : Not all prompts are created equal! │
│ => A 4,000-token prompt saturates the KV-Cache 20x more than short queries.│
└─────────────────────────────────────────────────────────────────────────────┘
To enable predictive, smooth, and cost-effective scaling, Kubernetes must monitor the internal state of the continuous batching iteration loop via metrics exposed by the vLLM /metrics endpoint.
2. Key vLLM Metrics for Production Autoscaling
vLLM natively exposes high-fidelity Prometheus metrics. Three core signals form the foundation of intelligent autoscaling:
vllm:num_requests_waiting: The count of incoming requests queued in vLLM’s internal scheduling queue waiting for available KV-Cache blocks. Any value above zero indicates immediate compute saturation.vllm:gpu_cache_usage_factor: The proportion of KV-Cache memory blocks currently allocated for active decoding sequences (normalized from0.0to1.0).vllm:time_to_first_token_seconds_bucket/vllm:time_per_output_token_seconds: The effective end-to-end token latency experienced by clients, ideal for alerting and SLA guardrails.
┌─────────────────────────────────────────────────────────┐
│ Ingress Traffic (Incoming LLM Requests) │
└────────────────────────────┬────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ OpenShift AI / KServe InferenceService (vLLM) │
│ ┌─────────────────────────────────────────────────┐ │
│ │ Metrics Exporter: /metrics │ │
│ │ • vllm:gpu_cache_usage_factor │ │
│ │ • vllm:num_requests_waiting │ │
│ └────────────────────────┬────────────────────────┘ │
└────────────────────────────┼────────────────────────────┘
│ Scrape (10s)
▼
┌─────────────────────────────────────────────────────────┐
│ OpenShift User-Workload Monitoring │
│ (Prometheus / Thanos) │
└────────────────────────────┬────────────────────────────┘
│ Query PromQL
▼
┌─────────────────────────────────────────────────────────┐
│ KEDA Autoscaling Operator │
│ (ScaledObject: triggers on cache > 0.85 or waiting > 2) │
└────────────────────────────┬────────────────────────────┘
│ Scale Out / Scale In
▼
┌─────────────────────────────────────────────────────────┐
│ OpenShift GPU Orchestrator (DRA / MachineSet) │
│ Spawns new vLLM Pods on available GPU Worker Nodes │
└─────────────────────────────────────────────────────────┘
3. Declarative Architecture: KEDA & ScaledObject Configuration
On Red Hat OpenShift, KEDA is deployed directly via OperatorHub and natively integrates with OpenShift User-Workload Monitoring to query Prometheus metrics securely.
Step 1: Enable the ServiceMonitor for vLLM
This manifest instructs OpenShift Monitoring to scrape the vLLM runtime metrics every 10 seconds:
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: vllm-metrics-monitor
namespace: ai-inference-prod
labels:
app.kubernetes.io/name: vllm-granite-3b
spec:
selector:
matchLabels:
serving.kserve.io/inferenceservice: granite-3b-instruct
endpoints:
- port: metrics
path: /metrics
interval: 10s
scrapeTimeout: 5s
Step 2: Define KEDA TriggerAuthentication for Thanos Querier
To securely allow KEDA to query OpenShift’s internal Thanos metrics endpoint:
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
name: keda-trigger-auth-prometheus
namespace: ai-inference-prod
spec:
secretTargetRef:
- parameter: bearerToken
name: thanos-querier-token
key: token
- parameter: ca
name: thanos-querier-ca
key: ca.crt
Step 3: Deploy the Multi-Trigger KEDA ScaledObject
The following ScaledObject dynamically adjusts the vLLM replica count between 1 and 8 pods based on dual criteria:
- If
vllm:num_requests_waitingexceeds 2 pending requests. - If the average
vllm:gpu_cache_usage_factorexceeds 0.80 (80% KV-Cache utilization).
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: vllm-granite-scaledobject
namespace: ai-inference-prod
spec:
scaleTargetRef:
apiVersion: serving.kserve.io/v1beta1
kind: InferenceService
name: granite-3b-instruct
minReplicaCount: 1
maxReplicaCount: 8
cooldownPeriod: 300 # 5-minute cooldown prevents rapid scale-in thrashing
pollingInterval: 15 # Evaluation interval
advanced:
horizontalPodAutoscalerConfig:
behavior:
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Pods
value: 1
periodSeconds: 60
triggers:
- type: prometheus
metadata:
serverAddress: https://thanos-querier.openshift-monitoring.svc.cluster.local:9091
metricName: vllm_waiting_requests_trigger
threshold: '2'
query: sum(vllm:num_requests_waiting{namespace="ai-inference-prod", model_name="granite-3b-instruct"})
authModes: bearer
authenticationRef:
name: keda-trigger-auth-prometheus
- type: prometheus
metadata:
serverAddress: https://thanos-querier.openshift-monitoring.svc.cluster.local:9091
metricName: vllm_kv_cache_pressure_trigger
threshold: '0.80'
query: avg(vllm:gpu_cache_usage_factor{namespace="ai-inference-prod", model_name="granite-3b-instruct"})
authModes: bearer
authenticationRef:
name: keda-trigger-auth-prometheus
4. Overcoming the GPU “Cold Start” Challenge on OpenShift
While KEDA triggers pod scaling in milliseconds, the actual spin-up time for a vLLM pod (Cold Start) can range between 45 to 120 seconds due to:
- Dynamic GPU node provisioning via OpenShift MachineSets / Cluster Autoscaler.
- Model weight transfer (10 GB to 70 GB) from S3/Ceph object storage.
- CUDA kernel compilation and PyTorch execution graph initialization.
Engineering Best Practices to Mitigate Cold Starts:
- Shared ReadWriteMany Model Cache (ODF / CephFS / Lustre): Mount a shared read-only cache volume so newly spawned pods instantly access model weights without downloading over the network.
- Warm Pools & Pre-warmed Worker Nodes: Maintain at least one active replica (
minReplicaCount: 1) and keep pre-pulled container images across GPU nodes. - Conservative Scale-In Cooldown: Set a
cooldownPeriodof at least 300 seconds (5 minutes) to avoid terminating recently warmed GPU pods right before a follow-up burst.
5. Autoscaling Strategies Comparison for Production LLMs
| Evaluation Criteria | Standard HPA (CPU / RAM) | Custom HPA (GPU Memory Util) | KEDA + vLLM Metrics (KV-Cache & Queue) |
|---|---|---|---|
| Signal Accuracy | Zero (completely uncorrelated) | Misleading (VRAM pre-allocated at 90%) | Maximal (real continuous batching pressure) |
| Burst Reactivity | Extremely slow | Ineffective | Instantaneous (triggers on requests_waiting > 2) |
| Long Context Handling | Blind | Blind | Native (direct tracking of KV-Cache allocation) |
| GPU Cost Optimization | Poor (high OOM crash risk) | Poor (permanent over-provisioning) | Optimal (surgical scale-out and controlled scale-in) |
| OpenShift Integration | Basic | Requires NVIDIA GPU Operator | Seamless via KEDA Operator + OpenShift Monitoring |
6. Platform & LLMOps Implementation Checklist
To successfully industrialize LLM autoscaling across your enterprise clusters:
- Always enable vLLM Prometheus metrics: Ensure
--disable-log-statsis disabled and the metrics port is routed to your ServiceMonitor. - Combine dual triggers: Pair memory pressure (
gpu_cache_usage_factor) for long context prompts with queue depth (num_requests_waiting) for concurrent user surges. - Monitor Time-To-First-Token (TTFT): If median TTFT breaches 800 ms, tighten the trigger thresholds to scale out more aggressively.
- Enforce Declarative GitOps (ArgoCD): Store all
ScaledObject,ServiceMonitor, andTriggerAuthenticationmanifests in Git for reproducible multi-cluster deployments.
Master Production AI Systems Engineering with Aperta Scientia
Deploying and scaling enterprise foundation models at scale requires dual mastery: expert Cloud-Native Kubernetes orchestration and deep optimization of GenAI inference engines.
Aperta Scientia prepares your engineering teams for these cutting-edge challenges:
- AS300 — AI Platform Engineer: The elite 3-month curriculum to master OpenShift AI (RHOAI), vLLM optimization, event-driven scaling with KEDA, declarative serving with KServe, vector databases with Milvus, and governance with TrustyAI.
- AS200 — New DevOps Platform Engineer : The foundational curriculum to design resilient Red Hat OpenShift clusters, automate with GitOps (ArgoCD), implement robust Prometheus / Thanos observability, and manage multi-cluster environments with RHACM.
Apply these technologies in production
Explore our intensive 3-month AS200 (DevOps) and AS300 (AI Platform Engineer) curriculums.