0%·8 min left
Kubernetes

Automated Pod Rightsizing Without Restarts: Why VPA's Tradeoff Is Optional Now

Ivan Čilić

Ivan Čilić

Technical Staff

August 14, 20268 min read
Automated Pod Rightsizing Without Restarts: Why VPA's Tradeoff Is Optional Now

Automated pod rightsizing continuously adjusts CPU and memory requests to match what workloads actually use, instead of what engineers guessed at deploy time. It used to require restarting pods, so most teams turned it off. That constraint is gone: resource changes now land on running pods, either in place or through live migration, and connections and in-memory state survive either way.

Why your cluster is overprovisioned in the first place#

Nobody sizes resource requests with data. An engineer copies the requests from a neighboring deployment, doubles them to be safe, and ships. Multiply that across hundreds of services and you get the number that shows up in every cost review: clusters running at 20 to 30 percent utilization while the cloud bill grows.

The fix sounds simple. Profile each workload, set requests to match observed usage, repeat as usage changes. But doing that manually across a real fleet is a job that never ends. Usage shifts with every release and every traffic pattern, so a workload rightsized in March is wrong again by June. Manual tuning does not scale, which is why the rightsizing category exists at all.

Why automation became a tradeoff instead of a fix#

Kubernetes has shipped a rightsizing tool for years: the Vertical Pod Autoscaler. VPA watches usage and updates requests automatically. The catch is in how it applies changes. To give a pod new resource values, VPA evicts it and recreates it.

That eviction has a cost. Anything mid-request when the pod dies gets an error or a retry. In-memory state disappears, so caches go cold and JVMs re-warm while latency climbs. Pod disruption budgets exist to limit exactly this kind of churn, which means aggressive rightsizing either violates them or stalls behind them. And a fleet-wide rightsizing pass, viewed from your monitoring, can look a lot like an incident.

So platform teams face a choice: accept continuous disruption in exchange for efficiency, or accept waste in exchange for stability. Almost everyone picks stability. VPA runs in recommendation-only mode, the recommendations pile up in a dashboard, and the overprovisioning stays. This is the pattern behind most stalled Kubernetes cost projects. The tooling could act, but acting hurts, so it only observes.

In-place resize helps, within limits#

Kubernetes itself has been closing part of this gap. In-place pod vertical scaling shipped as beta in 1.33 and stable in 1.35, letting the kubelet patch a running pod's CPU and memory through the resize subresource. The container's cgroup limits change and nothing restarts.

DevZero uses this path whenever the cluster supports it. But in-place resize has hard boundaries. A resize cannot change the pod's QoS class. It only covers CPU and memory, so GPU and hugepages changes still force a restart.

Memory-limit decreases work in place on Kubernetes 1.34 and newer, but they carry a risk the increase path doesn't. The kubelet refuses to shrink a limit below what the container is already using — the resize just stalls with an error — but a decrease that lands only slightly above live usage applies cleanly, and then an ordinary traffic spike crosses the new limit and OOM-kills a running container with no warning. Lowering a running container's memory ceiling is the workload owner's call, not the platform's, which is why DevZero applies in-place memory-limit decreases only for workloads that explicitly opt in. Everything else keeps the safe default.

And most importantly, the new values have to fit on the node where the pod is already running. If the node lacks headroom, the API server accepts the resize and the kubelet marks it infeasible, and no amount of patching will fix that. The pod is simply on the wrong node.

For VPA and most rightsizing tools, every one of those cases means the same thing it always did: evict and recreate.

What zero-restart rightsizing changes#

DevZero closes the remaining gap with CRIU-based live migration. When an in-place resize is not feasible, the platform checkpoints the running container, moves it to a node that has the required capacity, and resumes it with memory, connections, and process state intact. A restore creates a fresh pod spec, so restrictions that bind a live pod — like the immutable QoS class — don't apply, and there is no dependency on node headroom, because the pod goes where the resources are. Between the two mechanisms, every recommendation gets applied without an application restart.

That makes the behavior VPA promised actually safe to run. Requests track real usage continuously instead of on a quarterly review cycle. Each pod is evaluated on its own metrics, so a hot replica scales up while an idle one scales down, a granularity that rolling restarts make impossible because they force a uniform spec. Migration is not an eviction, so disruption budgets never become the bottleneck. And developers can keep copy-pasting generous requests, because the platform corrects them without a ticket or a restart window.

This is the difference between visibility and actuation. Plenty of tools will tell you which pods are oversized. The hard part was always acting on that information without breaking things, and restarts were the reason it was hard.

In-place resize vs. checkpoint/restore: which mechanism handles what#

The two mechanisms are complementary, not interchangeable. In-place resize is the lightest touch — the pod never moves — so it goes first. Checkpoint/restore covers everything in-place resize structurally can't.

In-place resizeCRIU live migration
How it worksThe kubelet patches the running pod through the resize subresource and updates cgroup limits on the node it's already onThe platform checkpoints the full process state — memory pages, open connections, file descriptors — and restores it on another node
The pod objectSame pod, same nodeA new pod spec; the application process resumes exactly where it left off
Node headroomRequired — the new values must fit the current node, or the resize is marked infeasibleNot required — the pod moves to a node that has the capacity
QoS class changeRejected — Kubernetes treats QoS class as immutable on a running podHandled — the restored pod carries a fresh spec, so the class can change while memory and connections survive
Memory-limit decreasesIn place on Kubernetes 1.34+, gated behind an explicit per-workload opt-in because of the OOM riskHandled — the workload resumes under the new limits on the target node
GPU and hugepagesNot covered — CPU and memory onlyHandled — the restored pod carries the new resource spec
Kubernetes version1.33+ (beta), stable in 1.35Any version
What the application seesNothing — cgroups change under itNothing — memory, connections, and process state survive the move

How it fits with HPA and KEDA#

Rightsizing does not replace your autoscaling. HPA and KEDA change how many replicas exist in response to load, while rightsizing changes how big each replica is. They work better together: when each pod's requests are accurate, HPA's scaling math runs on real numbers instead of inflated ones, so it scales at the right moments. If you have tuned KEDA scalers you are happy with, nothing about them changes.

How to evaluate rightsizing software#

Three questions separate tools in this category quickly.

  1. How are changes applied when in-place resize is not feasible? Every vendor can patch a pod on a node with spare headroom. Ask what happens when the node is full, the QoS class would change, or the workload is stateful. If the answer is eviction, you have found the disruption.
  2. Does it optimize placement, or only requests? Shrinking requests without moving pods leaves stranded capacity on oversized nodes. The savings show up when pod sizing and node selection are solved together.
  3. Will your team actually leave it in automatic mode? Recommendation-mode tools produce reports. Savings come from actuation, and actuation only survives in production if it causes no disruption.

Frequently Asked Questions#

What is automated pod rightsizing?#

It is the continuous adjustment of Kubernetes CPU and memory requests to match observed usage, performed by software rather than engineers editing YAML. Done well, it closes the gap between requested and used resources, which is typically the largest source of Kubernetes waste.

Does Kubernetes rightsizing require restarting pods?#

Not anymore. Kubernetes 1.33+ can resize CPU and memory on a running pod in place — including memory-limit decreases on 1.34 and newer — and CRIU-based live migration covers the cases in-place resize cannot: QoS class changes, GPU and hugepages changes, and pods that need to move to a node with more capacity. Used together, resource changes land without an application restart.

How is rightsizing different from autoscaling?#

Autoscaling (HPA, KEDA) changes replica counts in response to load. Rightsizing changes the resource requests of each replica. Most overprovisioned clusters are wasting money per pod, which autoscaling cannot fix.

How do you optimize Kubernetes without manual tuning?#

Use a platform that profiles workloads continuously and applies corrections automatically. What makes this safe to leave on is zero-restart actuation, so corrections never cause the disruption that forces teams back to manual review.

Share:
Ivan Čilić

Ivan Čilić

Technical Staff

Cut Kubernetes Cost Before You Pay a Cent.

Every feature unlocked. No hidden fees.

Start for free

Start Free

$0/ month
Unlimited clusters
K8s resource & cost monitoring
Network monitoring
Cost attribution for departments
Multi-cloud support & governance
Audit logging