[{"data":1,"prerenderedAt":427},["ShallowReactive",2],{"blog-en-kubernetes-hpa-vpa-autoscaling-conflict-design":3,"blog-related-en-kubernetes-hpa-vpa-autoscaling-conflict-design":381,"blog-en-kubernetes-hpa-vpa-autoscaling-conflict-design-alt":370},{"id":4,"title":5,"author":6,"body":7,"date":364,"description":365,"extension":366,"image":367,"locale":368,"meta":369,"navigation":370,"path":371,"seo":372,"stem":373,"tags":374,"__hash__":380},"blog\u002Fblog\u002Fen\u002Fkubernetes-hpa-vpa-autoscaling-conflict-design.md","\"Running Both Feels Safer\" Is the Trap. Why Combining HPA and VPA in Kubernetes Can Send Autoscaling Into a Spiral","Kubo Team",{"type":8,"value":9,"toc":356},"minimark",[10,18,21,24,29,32,56,59,74,78,84,87,98,101,104,119,134,138,144,151,168,175,184,188,194,201,281,290,311,314,322,326,329,335,347],[11,12,13],"p",{},[14,15],"img",{"alt":16,"src":17},"section01","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fen\u002Fkubernetes-hpa-vpa-autoscaling-conflict-design\u002Fsection01.webp",[11,19,20],{},"You want to optimize both CPU and memory automatically, so you enable Kubernetes' HorizontalPodAutoscaler (HPA) and VerticalPodAutoscaler (VPA) on the same Deployment. Replica count and per-pod resource sizing, both handled by controllers instead of manual tuning — it sounds like the operational dream.",[11,22,23],{},"In practice, though, running HPA and VPA on the same resource metric (CPU or memory) can make the two automations keep rewriting each other's inputs, sending scaling into an endless \"death spiral.\" The official Kubernetes documentation explicitly warns against this configuration. This article breaks down why combining HPA and VPA causes incidents, and walks through design patterns for using both safely in production.",[25,26,28],"h2",{"id":27},"_1-why-running-both-doesnt-mean-fully-covered","1. Why \"Running Both\" Doesn't Mean \"Fully Covered\"",[11,30,31],{},"HPA and VPA are both filed under \"autoscaling,\" but what they actually control is completely different.",[33,34,35,46],"ul",{},[36,37,38,42,43],"li",{},[39,40,41],"strong",{},"HPA (horizontal scaling)",": watches a metric like CPU utilization and adjusts the ",[39,44,45],{},"number of pod replicas",[36,47,48,51,52,55],{},[39,49,50],{},"VPA (vertical scaling)",": observes a pod's actual resource consumption and adjusts the ",[39,53,54],{},"CPU\u002Fmemory request and limit"," of that pod itself",[11,57,58],{},"Because the two roles are distinct, it's natural to think: \"If HPA scales out while VPA right-sizes each pod, we get maximum resource efficiency.\" Indeed, the general guidance is to use HPA for stateless, bursty workloads and VPA for stateful or single-instance workloads with inconsistent resource needs.",[11,60,61,62,65,66,73],{},"The trouble starts when both are enabled ",[39,63,64],{},"on the same Deployment, targeting the same metric"," (CPU, for example) at the same time. This kind of incompatibility between autoscalers is hard to spot just by staring at pod manifests. A management console like ",[67,68,72],"a",{"href":69,"rel":70},"https:\u002F\u002Fkubo.hexabase.io\u002F",[71],"nofollow","Kubo"," that visualizes your autoscaling configuration makes it much easier to catch, at design time, whether HPA and VPA are fighting over the same metric.",[25,75,77],{"id":76},"_2-the-mechanism-when-the-utilization-denominator-moves-hpa-misjudges","2. The Mechanism — When the Utilization Denominator Moves, HPA Misjudges",[11,79,80],{},[14,81],{"alt":82,"src":83},"section02","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fen\u002Fkubernetes-hpa-vpa-autoscaling-conflict-design\u002Fsection02.webp",[11,85,86],{},"HPA calculates CPU utilization with the following formula:",[88,89,94],"pre",{"className":90,"code":92,"language":93},[91],"language-text","utilization = current CPU usage ÷ CPU request × 100\n","text",[95,96,92],"code",{"__ignoreMap":97},"",[11,99,100],{},"Now suppose VPA decides, \"usage is low relative to the request, let's lower the request,\" and rewrites it. Even if usage doesn't change, the denominator (request) just got smaller, so the calculated utilization spikes. Conversely, if VPA raises the request, utilization appears to drop.",[11,102,103],{},"This property creates the following feedback loop:",[105,106,107,110,113,116],"ol",{},[36,108,109],{},"HPA scales out, adding replicas, which lowers the load per pod",[36,111,112],{},"VPA records that lower load in its history and recommends a smaller request",[36,114,115],{},"Because the request dropped, the same usage now computes to a higher utilization",[36,117,118],{},"HPA sees the \"spike\" in utilization and scales out even further",[11,120,121,122,127,128,133],{},"Repeat this cycle and replica count and resource requests keep oscillating without ever converging. The ",[67,123,126],{"href":124,"rel":125},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fconcepts\u002Fworkloads\u002Fautoscaling\u002Fvertical-pod-autoscale\u002F",[71],"official Kubernetes documentation"," spells out VPA's updateMode options and prerequisites in detail, precisely because the division of labor with HPA matters. ",[67,129,132],{"href":130,"rel":131},"https:\u002F\u002Fscaleops.com\u002Fblog\u002Fhpas-three-architectural-flaws-and-why-your-autoscaling-keeps-failing\u002F",[71],"ScaleOps' analysis",", a cloud-native operations blog, calls this a \"documented anti-pattern\" that engineers keep stumbling into unintentionally.",[25,135,137],{"id":136},"_3-the-symptom-restart-loops-compounded-by-vpas-pod-recreation","3. The Symptom: \"Restart Loops\" Compounded by VPA's Pod Recreation",[11,139,140],{},[14,141],{"alt":142,"src":143},"section03","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fen\u002Fkubernetes-hpa-vpa-autoscaling-conflict-design\u002Fsection03.webp",[11,145,146,147,150],{},"Layer one more VPA behavior on top of the feedback loop above, and the symptoms get even harder to diagnose. VPA has historically applied resource changes by ",[39,148,149],{},"evicting and recreating the pod",". When that recreation overlaps with HPA adding or removing replicas, the whole cluster can look like it's suffering from \"unexplained restarts.\"",[11,152,153,154,157,158,163,164,167],{},"The Kubernetes ecosystem has been chipping away at this problem. ",[39,155,156],{},"In-Place Pod Resize"," — which rewrites a running container's CPU\u002Fmemory request and limit without recreating the pod — reached General Availability as part of Kubernetes 1.35 in a December 2025 update. According to the ",[67,159,162],{"href":160,"rel":161},"https:\u002F\u002Fkubernetes.io\u002Fblog\u002F2025\u002F12\u002F19\u002Fkubernetes-v1-35-in-place-pod-resize-ga\u002F",[71],"official Kubernetes blog",", it took over six years from its alpha debut in v1.27 to reach this point, finally allowing resource changes to be applied without deleting the pod. VPA now has a corresponding ",[95,165,166],{},"InPlaceOrRecreate"," mode, which attempts an in-place update first and only falls back to the old eviction-based Recreate behavior when an in-place update isn't possible.",[11,169,170,171,174],{},"The important caveat: ",[39,172,173],{},"In-Place Pod Resize reduces the \"recreation cost\" of VPA — it does not resolve the underlying feedback loop with HPA."," Fewer restarts doesn't mean the utilization-denominator problem goes away. Teams that mistake reduced symptoms for \"it's safe to run both now\" and skip the underlying design review are setting themselves up for a repeat.",[11,176,177,178,183],{},"There are other examples of autoscaling faithfully chasing a worsening metric straight into an oversized incident. ",[67,179,182],{"href":180,"rel":181},"https:\u002F\u002Fkomodor.com\u002Fblog\u002Fcompany-autoscales-to-200-nodes-and-crashe-the-app\u002F",[71],"A case documented by Komodor"," describes a code change that steadily degraded CPU load over time; HPA kept reacting to it, scaling pod count from a normal 30 up to 4,000 and ballooning the node count to 200, turning into a 4.5-hour incident. HPA itself behaved exactly as designed — but when nobody addresses the root cause of a worsening metric and leaves everything to automation, the scale-out never gets corrected and just keeps growing. That's a lesson that applies directly to the HPA\u002FVPA conflict as well.",[25,185,187],{"id":186},"_4-three-design-patterns-for-safe-combined-use","4. Three Design Patterns for Safe Combined Use",[11,189,190],{},[14,191],{"alt":192,"src":193},"section04","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fen\u002Fkubernetes-hpa-vpa-autoscaling-conflict-design\u002Fsection04.webp",[11,195,196,197,200],{},"None of this means HPA and VPA can never be used together. As long as you avoid having ",[39,198,199],{},"both rewrite the same metric at the same time",", you can combine them safely. Three patterns show up repeatedly in practice.",[202,203,204,220],"table",{},[205,206,207],"thead",{},[208,209,210,214,217],"tr",{},[211,212,213],"th",{},"Pattern",[211,215,216],{},"Design point",[211,218,219],{},"Best suited for",[221,222,223,252,265],"tbody",{},[208,224,225,231,249],{},[226,227,228],"td",{},[39,229,230],{},"① Set updateMode to Initial\u002FOff",[226,232,233,234,237,238,241,242,245,246],{},"Keep HPA active, but set VPA's ",[95,235,236],{},"updateMode"," to ",[95,239,240],{},"Initial"," (apply recommendations only at pod creation) or ",[95,243,244],{},"Off"," (recommendations only, no auto-apply) instead of ",[95,247,248],{},"Auto",[226,250,251],{},"HPA is already running and you only want VPA's recommendations as a reference",[208,253,254,259,262],{},[226,255,256],{},[39,257,258],{},"② Separate the metrics",[226,260,261],{},"HPA scales on CPU utilization, VPA only optimizes the memory request — splitting which autoscaler owns which metric",[226,263,264],{},"CPU and memory have different load characteristics and you want to auto-optimize both",[208,266,267,272,278],{},[226,268,269],{},[39,270,271],{},"③ Custom metrics + recommend-only mode",[226,273,274,275,277],{},"HPA scales on a custom metric like request count, while VPA stays in ",[95,276,244],{}," mode purely to refine resource estimates",[226,279,280],{},"You want traffic-driven scale-out alongside improving resource sizing over time",[11,282,283,284,289],{},"Pattern ① is safe for a simple reason: once a pod is created, its request is fixed, and nothing changes it while the pod is running. That keeps the denominator HPA relies on stable, so the feedback loop can't occur in the first place. ",[67,285,288],{"href":286,"rel":287},"https:\u002F\u002Fwww.fairwinds.com\u002Fblog\u002Fanswering-your-goldilocks-questions-about-how-hpa-and-vpa-work-together",[71],"Fairwinds",", the team behind the VPA-adoption tool Goldilocks, likewise recommends disabling VPA's updater (the component that auto-applies changes) and keeping it focused on recommendations whenever HPA is active.",[11,291,292,293,298,299,304,305,310],{},"Separating the target metric or scaling signal, as in patterns ② and ③, is a well-established approach repeatedly covered in ",[67,294,297],{"href":295,"rel":296},"https:\u002F\u002Fcast.ai\u002Fblog\u002Fhpa-vs-vpa\u002F",[71],"comparisons of Kubernetes autoscaling options"," and ",[67,300,303],{"href":301,"rel":302},"https:\u002F\u002Fsedai.io\u002Fblog\u002Fhpa-vs-vpa",[71],"cloud monitoring and cost-optimization write-ups",". ",[67,306,309],{"href":307,"rel":308},"https:\u002F\u002Foneuptime.com\u002Fblog\u002Fpost\u002F2026-02-09-vpa-hpa-together-cpu-memory-autoscaling\u002Fview",[71],"An implementation example from OneUptime"," enforces a strict split — \"HPA scales on CPU (or a custom metric), VPA optimizes memory only, in Off\u002FInitial mode\" — and states plainly that \"both autoscalers watching the same metric should always be avoided.\"",[11,312,313],{},"Either way, remember to exclude sidecar containers (like the Istio proxy) from VPA's scope. If VPA starts changing sidecar resources too, it can introduce a separate inconsistency on the service mesh side.",[11,315,316,317,321],{},"Figuring out which controller owns which metric gets harder to keep straight as your cluster count grows. ",[67,318,320],{"href":69,"rel":319},[71],"Kubo Cloud","'s Captain UI visualizes autoscaling configuration — including HPA and VPA — in one place, which helps keep design reviews from turning into a black box.",[25,323,325],{"id":324},"summary","Summary",[11,327,328],{},"HPA and VPA are both powerful pieces of Kubernetes' autoscaling story, but \"running both feels safer\" is a dangerous assumption. When both make decisions against the same metric at once, the utilization denominator keeps shifting, creating a feedback loop where replica count and resource requests never converge.",[11,330,331,332,334],{},"The fix is straightforward: set VPA's ",[95,333,236],{}," to Initial or Off so it stays out of HPA's way, or separate the metrics each autoscaler owns — say, CPU for HPA and memory for VPA. In-Place Pod Resize reaching GA in 2026 lowered the cost of restarts, but that's a symptom fix, not a substitute for deciding up front which automation owns what.",[11,336,337,338,341,342,346],{},"Every time you add another autoscaling configuration to production, reviewing these structural pitfalls takes real engineering time. ",[67,339,72],{"href":69,"rel":340},[71],"'s Captain UI lets you inspect HPA and VPA settings for a workload through a visualized console, so you can see exactly which controller is rewriting what instead of treating it as a black box. Compared to designing and operating the same setup from scratch on EKS or AKS, ",[67,343,345],{"href":69,"rel":344},[71],"starting at ¥48,000\u002Fmonth"," for a full K3s-based Kubernetes environment is also appealing if your team would rather not burn time on this exact class of operational pitfall.",[11,348,349,350,355],{},"If you're wrestling with HPA and VPA together, start by deciding which metric belongs to which autoscaler. And if you're evaluating a managed platform to run it on, ",[67,351,354],{"href":352,"rel":353},"https:\u002F\u002Fwww.hexabase.com\u002Fcontact-us\u002F",[71],"reach out to us"," — we're happy to talk through it.",{"title":97,"searchDepth":357,"depth":357,"links":358},2,[359,360,361,362,363],{"id":27,"depth":357,"text":28},{"id":76,"depth":357,"text":77},{"id":136,"depth":357,"text":137},{"id":186,"depth":357,"text":187},{"id":324,"depth":357,"text":325},"2026-10-07","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.","md","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fen\u002Fkubernetes-hpa-vpa-autoscaling-conflict-design\u002Ftitle.webp","en",{},true,"\u002Fblog\u002Fen\u002Fkubernetes-hpa-vpa-autoscaling-conflict-design",{"title":5,"description":365},"blog\u002Fen\u002Fkubernetes-hpa-vpa-autoscaling-conflict-design",[375,376,377,378,379],"k3s","kubernetes","hpa","vpa","autoscaling","mf2MyEeMCXJBYN-ddKKHAtqarzSO7siNv2W_MKBF-xE",[382,389,397,404,412,421],{"path":383,"title":384,"description":385,"date":386,"tags":387},"\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",[375,376,377,378,379,388],"metrics-server",{"path":390,"title":391,"description":392,"date":393,"tags":394},"\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",[375,376,377,395,379,396],"containerresource","service-mesh",{"path":398,"title":399,"description":400,"date":401,"tags":402},"\u002Fblog\u002Fen\u002Fk3s-vpa-inplaceorrecreate-pod-resize-cgroup","VPA InPlaceOrRecreate Didn't Stop the Restart. Testing InPlacePodVerticalScaling on K3s","Does VPA's InPlaceOrRecreate mode and In-Place Pod Resize really avoid Pod restarts? We test QoS class constraints and the cgroup v1 trap on K3s with real configs and kubectl commands.","2026-10-17",[375,376,378,379,403],"cgroup",{"path":405,"title":406,"description":407,"date":408,"tags":409},"\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",[375,376,377,410,379,411],"prometheus-adapter","observability",{"path":413,"title":414,"description":415,"date":416,"tags":417},"\u002Fblog\u002Fen\u002Fk3s-keda-hpa-event-driven-autoscaling-decision","CPU Usage Looks Normal, But Requests Are Piling Up. When to Add KEDA to HPA in Kubernetes","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.","2026-10-03",[375,376,418,377,379,419,420],"keda","event-driven-scaling","scaledobject",{"path":422,"title":423,"description":424,"date":425,"tags":426},"\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",[375,376,377,418,379],1792592644537]