In-Place Vertical Scaling
How DevZero resizes pod CPU and memory without restarting pods, when it falls back to rolling restarts, and what the Kubernetes runtime requires.
In-Place Vertical Scaling
Overview
In-place vertical scaling lets Kubernetes adjust a pod's CPU and memory without restarting it. DevZero's Workload Operator uses this when a workload policy recommends different resource values and the cluster supports it — patching the running pod via the /resize subresource rather than triggering a rolling restart.
The operative phrase is when feasible. Not every resize qualifies: changing a pod's QoS class, an unsupported container runtime, or a node that can't accommodate the new values can all block an in-place resize. When DevZero detects these conditions, it falls back automatically to a rolling restart so the recommendation is always applied.
In-place vertical scaling is exclusively about CPU and memory on running pods. It has nothing to do with replica counts or horizontal scaling.
Kubernetes Version Requirements
| Kubernetes Version | Status | Feature Gate |
|---|---|---|
| < 1.27 | Not supported | — |
| 1.27 – 1.32 | Alpha | Must enable InPlacePodVerticalScaling on apiserver, scheduler, and kubelet |
| 1.33 – 1.34 | Beta | On by default; can be disabled |
| ≥ 1.35 | Stable | Permanently on; gate is locked |
Your container runtime must also support UpdateContainerResources — containerd v1.6+ and CRI-O both qualify.
Enabling In-Place Scaling
The operator verifies three conditions before attempting an in-place resize:
- The policy flag is enabled
- The cluster is running Kubernetes ≥ 1.33
- The
InPlacePodVerticalScalingfeature gate is active (on by default in 1.33+, locked on in 1.35+)
If any condition isn't met, the operator falls back to a standard rolling restart.
How DevZero Applies Resizes
An in-place resize patches the CPU and memory of a running pod's containers. Once the Kubernetes API accepts the change, the kubelet updates the container's cgroup limits — no restart, no downtime.
DevZero also keeps your workload's resource spec in sync so future pods (from rolling updates, node drains, or spontaneous restarts) inherit the updated values. How it handles that depends on the workload type:
| Workload Type | In-Place Resize | Resource Spec Updated? | Notes |
|---|---|---|---|
| Deployment | Yes | Yes | The operator pauses the Deployment, patches the pod template's CPU/memory values, then resumes — this prevents the Deployment controller from interpreting the resource change as a trigger for a rolling restart. |
| StatefulSet | Yes | No | Patching the StatefulSet's resource template would trigger a controller-managed rolling restart. Intentionally skipped — pods revert to original resource values if they restart. |
| DaemonSet | Yes | No | Same trade-off as StatefulSet. |
| Argo Rollout | Yes, across all active pod sets | No | Resizes pods in every currently active revision (e.g., both sides of a canary split) without triggering a new rollout. |
| CronJob | Yes | Yes (CronJob template only) | Future Job runs inherit the new resource values. |
| Standalone Pod | Yes | N/A | Direct /resize patch. |
For StatefulSets and DaemonSets, pods are resized in-place but the workload's resource template is intentionally not updated. If a pod restarts — OOM kill, node drain, anything — it comes back with the original spec resources until the next recommendation cycle runs.
Per-Pod Evaluation
When in-place scaling is active, DevZero evaluates each pod's metrics independently rather than applying a single aggregate recommendation uniformly across all replicas. A high-utilization pod can be scaled up while an underutilized one is scaled down — all without restarts. This granularity is only possible because there's no rolling restart forcing a uniform spec.
resizePolicy
resizePolicy is a per-container field that controls whether a resource change requires a container restart to take effect. If not set, all resources default to NotRequired (no restart needed).
resizePolicy:
- resourceName: cpu
restartPolicy: NotRequired
- resourceName: memory
restartPolicy: RestartContainerIf you resize CPU and memory simultaneously and either one has RestartContainer, the container restarts — the more restrictive policy wins. Pods with restartPolicy: Never must use NotRequired for all resources.
When In-Place Scaling Is Not Feasible
If you're running into multiple constraints here, live migration is worth considering. It applies resource changes by checkpointing and recreating the pod — no QoS class restrictions, no platform requirements, no node headroom dependency — while preserving the pod's running state via CRIU. The two approaches are complementary: DevZero can attempt in-place scaling first and fall back to live migration when needed.
Limitations
- Only CPU and memory can be resized in-place — GPU, hugepages, and ephemeral-storage always require a restart
- A pod's QoS class cannot change as a result of a resize
- On StatefulSets and DaemonSets, the resource template is not updated — pods revert to original values on restart
- Memory decreases can cause OOM kills if the container is already using more than the new limit
- When a node cannot satisfy the resize at all (
Infeasible), in-place scaling cannot help — live migration moves the pod to a node that already has the required capacity
Troubleshooting
Workload Optimization
How DevZero generates and applies workload optimization recommendations -- rightsizing, replica scaling, and live migration.
Live Migration
How DevZero applies resource changes to running pods using CRIU checkpoint-restore, preserving in-memory state and open connections without an application restart.