For most of Kubernetes' history, a pod's CPU and memory were fixed at creation. Changing them meant deleting the pod and starting a new one — and for a Java service, that restart throws away warmed-up JIT-compiled code, filled caches and connection pools. In-place pod resize, which reached GA in Kubernetes 1.35, removes that restart tax. For JVM applications, though, there's a catch that most write-ups skip.
CPU: resizes cleanly
When you raise or lower a container's CPU, Kubernetes updates its cgroup limits in place, and the change takes effect immediately at the operating-system level. The JVM keeps running with its warmed-up code. One nuance: thread pools the JVM sized at startup based on the CPU count — GC worker threads, the common ForkJoin pool — keep their original size. For most services that's fine; just don't expect a resize to re-tune everything the JVM decided at boot.
Memory: the JVM decided its heap at startup
A JVM calculates its maximum heap once, when it starts — from -Xmx or from -XX:MaxRAMPercentage applied to the memory limit it saw at that moment. If you raise the memory limit in place, the heap ceiling doesn't grow. The container has more memory; the JVM won't use it, and can still throw OutOfMemoryError with gigabytes of the new limit unused. Shrinking memory in place is riskier still, since the JVM may already be using more than the new limit allows.
The fix: a resize policy per resource
Kubernetes lets you declare, per resource, whether a resize needs a container restart. For JVM services, resize CPU in place and restart the container for memory:
With RestartContainer, a memory resize restarts only the container — not the whole pod — so it keeps its node, IP and volumes, and the JVM starts with a correctly sized heap. The default policy is NotRequired for both resources, which is exactly the wrong default for a JVM's memory, so set it explicitly.
Resizing a running pod
Resizes go through the pod's resize subresource (kubectl v1.32 or later):
The pattern Java teams actually want: startup CPU boost
JVM services need far more CPU while starting — class loading and JIT compilation — than at steady state. Before in-place resize, you either over-provisioned CPU all day or accepted slow starts. Now you can start with a generous CPU allocation and scale it down in place once the pod is ready, without a restart. Tools such as the Vertical Pod Autoscaler's in-place mode and the open-source Kube Startup CPU Boost project automate exactly this.
NotRequired, memory RestartContainer for every JVM container. Start with CPU-only resizes on stateless services, where the no-restart path is real. Run VPA in recommendation mode for a few weeks before letting it act. And watch for resizes stuck pending because the node lacks capacity.
For the rest of a production-ready setup — probes, graceful shutdown and heap sizing — see my Spring Boot on Kubernetes checklist.
Frequently asked questions
Is in-place pod resize generally available in Kubernetes?
Yes. In-place pod resize reached general availability in Kubernetes 1.35, allowing CPU and memory of running containers to be changed without recreating the pod.
Does the JVM use extra memory after an in-place resize?
Not without a restart. The JVM calculates its maximum heap at startup, so raising the container's memory limit in place does not raise the heap ceiling. Use restartPolicy: RestartContainer for memory on JVM containers.
Can I resize CPU for a Java application without restarting it?
Yes. CPU limits change in place and take effect immediately. Thread pools the JVM sized at startup, such as GC worker threads, keep their original size.
resizePolicy: CPU NotRequired, memory RestartContainer.