[{"data":1,"prerenderedAt":317},["ShallowReactive",2],{"blog-en-k3s-keda-hpa-event-driven-autoscaling-decision":3,"blog-related-en-k3s-keda-hpa-event-driven-autoscaling-decision":272,"blog-en-k3s-keda-hpa-event-driven-autoscaling-decision-alt":259},{"id":4,"title":5,"author":6,"body":7,"date":253,"description":254,"extension":255,"image":256,"locale":257,"meta":258,"navigation":259,"path":260,"seo":261,"stem":262,"tags":263,"__hash__":271},"blog\u002Fblog\u002Fen\u002Fk3s-keda-hpa-event-driven-autoscaling-decision.md","CPU Usage Looks Normal, But Requests Are Piling Up. When to Add KEDA to HPA in Kubernetes","Kubo Team",{"type":8,"value":9,"toc":239},"minimark",[10,15,23,34,43,47,53,62,71,74,78,84,93,98,101,105,114,118,121,130,134,140,147,174,177,191,204,218,222,225],[11,12,14],"h2",{"id":13},"cpu-usage-looks-normal-so-why-are-requests-piling-up","CPU Usage Looks Normal, So Why Are Requests Piling Up?",[16,17,18],"p",{},[19,20],"img",{"alt":21,"src":22},"section01","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fen\u002Fk3s-keda-hpa-event-driven-autoscaling-decision\u002Fsection01.webp",[16,24,25,26,33],{},"If you run Kubernetes's HorizontalPodAutoscaler (HPA) in production long enough, you'll eventually hit a situation where \"CPU and memory usage both look normal, but the system still can't keep up.\" The reason is structural: as the ",[27,28,32],"a",{"href":29,"rel":30},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fconcepts\u002Fworkloads\u002Fautoscaling\u002F",[31],"nofollow","official Kubernetes documentation"," defines it, HPA is \"a controller that periodically adjusts the number of replicas in a workload to match observed resource utilization, such as CPU or memory usage.\" It simply has no way to see signals that live outside the cluster, like queue depth or Kafka consumer lag.",[16,35,36,37,42],{},"The classic case is an async job worker or message-queue consumer. CPU load stays low while the backlog of pending messages keeps growing, and there's no way for HPA to detect that. This is exactly the gap that ",[27,38,41],{"href":39,"rel":40},"https:\u002F\u002Fwww.cncf.io\u002Fannouncements\u002F2023\u002F08\u002F22\u002Fcloud-native-computing-foundation-announces-graduation-of-kubernetes-autoscaler-keda\u002F",[31],"KEDA"," (Kubernetes Event-Driven Autoscaling), a graduated CNCF project, was built to fill. Whether you're running K3s-based Kubo or any other Kubernetes cluster, this \"HPA blind spot\" shows up in the same shape.",[11,44,46],{"id":45},"keda-doesnt-replace-hpa-it-complements-it","KEDA Doesn't Replace HPA — It Complements It",[16,48,49],{},[19,50],{"alt":51,"src":52},"section02","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fen\u002Fk3s-keda-hpa-event-driven-autoscaling-decision\u002Fsection02.webp",[16,54,55,56,61],{},"A common misunderstanding is treating \"KEDA vs HPA\" as an either-or comparison. In reality, as ",[27,57,60],{"href":58,"rel":59},"https:\u002F\u002Fkeda.sh\u002Fdocs\u002F2.21\u002Freference\u002Fscaledobject-spec\u002F",[31],"KEDA's official ScaledObject specification"," makes clear, KEDA automatically creates and manages the underlying HPA — it doesn't replace HPA itself.",[16,63,64,65,70],{},"The ",[27,66,69],{"href":67,"rel":68},"https:\u002F\u002Fgithub.com\u002Fkedacore\u002Fkeda",[31],"KEDA GitHub repository"," describes it as a component that provides \"fine-grained autoscaling (including to\u002Ffrom zero) for event driven Kubernetes workloads.\" When you create a ScaledObject, KEDA generates an HPA resource behind the scenes based on that definition, translating external event metrics into a form HPA can consume.",[16,72,73],{},"Structurally, HPA is the \"scaling execution engine,\" and KEDA sits in front of it as a \"metrics translation layer.\" Once replica count is at 1 or above, HPA drives the scaling; KEDA only controls the 0-to-1 activation. Miss this division of labor and assume \"KEDA replaces the need for HPA,\" and your combined setup will trip you up.",[11,75,77],{"id":76},"three-decision-axes-for-k3s-environments","Three Decision Axes for K3s Environments",[16,79,80],{},[19,81],{"alt":82,"src":83},"section03","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fen\u002Fk3s-keda-hpa-event-driven-autoscaling-decision\u002Fsection03.webp",[16,85,86,87,92],{},"The practical decision framework laid out in ",[27,88,91],{"href":89,"rel":90},"https:\u002F\u002Fwww.plural.sh\u002Fblog\u002Fkeda-vs-hpa-guide\u002F",[31],"this KEDA vs. HPA comparison guide"," boils down to three axes.",[94,95,97],"h3",{"id":96},"_1-is-the-metric-source-internal-or-external","1. Is the metric source internal or external?",[16,99,100],{},"For synchronous API servers or web frontends where CPU and memory directly reflect load, HPA alone is enough. But if you want to scale on signals that live outside the cluster — message queue depth, Kafka consumer lag, external cloud service queue length — that's where KEDA comes in.",[94,102,104],{"id":103},"_2-do-you-need-scale-to-zero","2. Do you need scale-to-zero?",[16,106,107,108,113],{},"HPA has a structural limitation: it can never scale below one replica. For async workers or batch jobs where you can't justify paying for an always-on replica, KEDA's ability to scale all the way down to zero during idle periods is a major advantage. ",[27,109,112],{"href":110,"rel":111},"https:\u002F\u002Fcast.ai\u002Fblog\u002Fkeda-kubernetes-event-driven-autoscaling\u002F",[31],"An analysis of KEDA's cost impact"," cites eliminating idle pods entirely as the single highest-impact cost-saving factor.",[94,115,117],{"id":116},"_3-burst-characteristics-of-the-load","3. Burst characteristics of the load",[16,119,120],{},"A gradually rising and falling load can be tracked fine by HPA's polling cycle. But sudden, bursty traffic — like the order-processing spike right after a flash sale starts — is better suited to KEDA's ability to react instantly to an external event trigger.",[16,122,123,124,129],{},"In most production environments, teams don't treat this as either-or; the common pattern is \"HPA for synchronous services, KEDA for async workers.\" This decision framework applies just as well on ",[27,125,128],{"href":126,"rel":127},"https:\u002F\u002Fdocs.k3s.io\u002F",[31],"a lightweight Kubernetes distribution"," like K3s.",[11,131,133],{"id":132},"tuning-pollinginterval-and-cooldownperiod-so-the-combination-doesnt-break","Tuning pollingInterval and cooldownPeriod So the Combination Doesn't Break",[16,135,136],{},[19,137],{"alt":138,"src":139},"section04","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fen\u002Fk3s-keda-hpa-event-driven-autoscaling-decision\u002Fsection04.webp",[16,141,142,143,146],{},"The most common practical mistake when combining HPA and KEDA is leaving the ScaledObject defaults untouched. According to ",[27,144,60],{"href":58,"rel":145},[31],", the key parameter defaults are:",[148,149,150,158,164],"ul",{},[151,152,153,157],"li",{},[154,155,156],"strong",{},"pollingInterval"," (default 30 seconds): how often each trigger is checked. This only governs the 0-to-1 scale-up; scaling from 1 to N is handled by the underlying HPA, running on its own sync cycle (default 15 seconds)",[151,159,160,163],{},[154,161,162],{},"cooldownPeriod"," (default 300 seconds): how long to wait after a trigger was last reported active before scaling back down",[151,165,166,169,170,173],{},[154,167,168],{},"minReplicaCount"," (default 0) \u002F ",[154,171,172],{},"maxReplicaCount"," (default 100): the lower and upper scaling bounds",[16,175,176],{},"Here's the trap: if minReplicaCount is set above 0, the workload can never scale to zero, and scaling control effectively shifts entirely to HPA. Most \"I installed KEDA but scale-to-zero isn't working\" incidents trace back to a misconfigured minReplicaCount, or a cooldownPeriod set too short for a workload with an expensive cold start. Keeping pollingInterval and cooldownPeriod close in value makes it easier to avoid the flapping that happens when scale-up and scale-down alternate rapidly.",[16,178,179,180,185,186,190],{},"If your only experience is a simple setup like the one in the ",[27,181,184],{"href":182,"rel":183},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Ftasks\u002Frun-application\u002Fhorizontal-pod-autoscale-walkthrough\u002F",[31],"HPA walkthrough"," — ",[187,188,189],"code",{},"kubectl autoscale deployment php-apache --cpu=50% --min=1 --max=10"," — it's easy to overlook these parameter dependencies once KEDA enters the picture. When designing a combined setup, confirm HPA's behavior on its own first, then verify each ScaledObject parameter one at a time.",[16,192,193,194,198,199,203],{},"If HPA itself has quirks in your K3s cluster, it's worth reviewing ",[27,195,197],{"href":196},"\u002Fblog\u002Fja\u002Fk3s-hpa-scaledown-stabilization-window-replica-flapping","why replica counts oscillate every few minutes"," and ",[27,200,202],{"href":201},"\u002Fblog\u002Fja\u002Fk3s-gpu-oomkilled-vpa-resource-estimation","the pitfalls of VPA resource estimation"," — both make it easier to reason about behavior once KEDA is added to the mix.",[16,205,206,207,212,213,217],{},"Building out this kind of combined autoscaling design and the monitoring stack behind it is easier on a managed Kubernetes environment that ",[27,208,211],{"href":209,"rel":210},"https:\u002F\u002Fkubo.hexabase.io\u002F",[31],"ships with Prometheus and Grafana built in"," on top of K3s — no need to build a metrics stack from scratch before you can even start testing. ",[27,214,216],{"href":209,"rel":215},[31],"Kubo","'s AI-Driven Deployment and Captain UI let you visualize and tune ScaledObject behavior as you go.",[11,219,221],{"id":220},"summary","Summary",[16,223,224],{},"HPA and KEDA aren't competing choices — they're layers with different jobs. HPA is the foundation, driven by internal resource metrics like CPU and memory; KEDA is the extension, driven by queue depth and external events. When you're unsure which to use in a K3s environment, start by working through three axes — is the metric source internal or external, do you need scale-to-zero, and is the load bursty — and if you do combine them, understanding the dependency between pollingInterval and cooldownPeriod is what keeps the tuning from backfiring.",[16,226,227,228,232,233,238],{},"If you want to validate this kind of combined setup cost-effectively, ",[27,229,231],{"href":209,"rel":230},[31],"Kubo Cloud"," runs full Kubernetes at roughly 58% of the cost of EKS. If you're trying to keep validation costs down, it's worth comparing ",[27,234,237],{"href":235,"rel":236},"https:\u002F\u002Fwww.hexabase.com\u002Fpricing\u002F",[31],"pricing plans",".",{"title":240,"searchDepth":241,"depth":241,"links":242},"",2,[243,244,245,251,252],{"id":13,"depth":241,"text":14},{"id":45,"depth":241,"text":46},{"id":76,"depth":241,"text":77,"children":246},[247,249,250],{"id":96,"depth":248,"text":97},3,{"id":103,"depth":248,"text":104},{"id":116,"depth":248,"text":117},{"id":132,"depth":241,"text":133},{"id":220,"depth":241,"text":221},"2026-10-03","KEDA and HPA aren't an either-or choice. When event-driven workloads grow on K3s\u002FKubernetes, here's why HPA alone hits its limits and how to decide when to add KEDA alongside it.","md","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fen\u002Fk3s-keda-hpa-event-driven-autoscaling-decision\u002Ftitle.webp","en",{},true,"\u002Fblog\u002Fen\u002Fk3s-keda-hpa-event-driven-autoscaling-decision",{"title":5,"description":254},"blog\u002Fen\u002Fk3s-keda-hpa-event-driven-autoscaling-decision",[264,265,266,267,268,269,270],"k3s","kubernetes","keda","hpa","autoscaling","event-driven-scaling","scaledobject","S_cP2oLIdTGARcrgDGfKvoOX6vw9PSvzcM-bbCY5-bc",[273,279,287,295,302,309],{"path":274,"title":275,"description":276,"date":277,"tags":278},"\u002Fblog\u002Fen\u002Fk3s-keda-vs-hpa-event-driven-autoscaling-decision","KEDA vs HPA on K3s: A Decision Framework for Event-Driven Autoscaling","When CPU\u002Fmemory-based HPA on K3s can't keep up with event-driven workloads, should you extend HPA or adopt KEDA, the CNCF-graduated project? Here's a 3-point decision framework, plus what to watch for on K3s.","2026-09-10",[264,265,267,266,268],{"path":280,"title":281,"description":282,"date":283,"tags":284},"\u002Fblog\u002Fen\u002Fk3s-hpa-containerresource-sidecar-utilization-dilution","HPA Was Scaling on the Sidecar's Share Too. The ContainerResource Blind Spot in Kubernetes","Kubernetes HPA sums resource usage across every container in a Pod, so Istio sidecars and logging agents dilute the scaling decision. Here's how the ContainerResource metric fixes it, in a K3s\u002FKubo context.","2026-10-21",[264,265,267,285,268,286],"containerresource","service-mesh",{"path":288,"title":289,"description":290,"date":291,"tags":292},"\u002Fblog\u002Fen\u002Fk3s-hpa-prometheus-adapter-discovery-interval-stale-metrics","Question Your discoveryInterval: Why K3s HPA Keeps Scaling on Stale Metrics from Prometheus Adapter","K3s HPA won't scale even though CPU usage looks normal. The culprit is a mismatch between Prometheus Adapter's metrics-relist-interval\u002Fmetrics-max-age and the HPA sync-period. Here's the three-layer delay chain and how to diagnose it.","2026-10-12",[264,265,267,293,268,294],"prometheus-adapter","observability",{"path":296,"title":297,"description":298,"date":299,"tags":300},"\u002Fblog\u002Fen\u002Fkubernetes-hpa-vpa-autoscaling-conflict-design","\"Running Both Feels Safer\" Is the Trap. Why Combining HPA and VPA in Kubernetes Can Send Autoscaling Into a Spiral","Enabling both HPA and VPA in Kubernetes can make two well-intentioned automations fight each other, sending autoscaling into an endless spiral. Here's why the conflict happens, and how to combine them safely with updateMode and metric separation.","2026-10-07",[264,265,267,301,268],"vpa",{"path":303,"title":304,"description":305,"date":306,"tags":307},"\u002Fblog\u002Fen\u002Fk3s-hpa-not-scaling-metrics-unknown-vpa-death-spiral","Your HPA Config Is Correct. So Why Won't Pods Scale? The Real Cause of 'Unknown Metrics' in K3s and the HPA\u002FVPA Death Spiral","You set up an HPA in K3s and Pods still won't scale. The usual culprits are unset resource requests silently disabling metrics, and a self-reinforcing HPA\u002FVPA feedback loop. Here's how to diagnose and fix it.","2026-09-02",[264,265,267,301,268,308],"metrics-server",{"path":310,"title":311,"description":312,"date":313,"tags":314},"\u002Fblog\u002Fen\u002Fkubernetes-hpa-vpa-autoscaling","The Complete Kubernetes Autoscaling Guide: HPA, VPA, and KEDA in Practice","Master Kubernetes autoscaling with HPA, VPA, and KEDA. Learn each tool's strengths, combination patterns, and cost optimization impact with practical examples.","2026-05-27",[265,268,267,301,266,315,316],"karpenter","cost-optimization",1792592636445]