Kubernetes 1.33 In-Place Pod Resizing: Change CPU & Memory Without Recreating Your Pod
Kubernetes 1.33 In-Place Pod Resizing: Change CPU & Memory Without Recreating Your Pod
Kubernetes 1.33 In-Place Pod Resizing: Change CPU & Memory Without Recreating Your Pod
There is a small Kubernetes feature that can make a surprisingly big difference in production.
Imagine you have a stateful application running inside a Pod. It is working perfectly, but its workload has increased.
You check the metrics:
CPU 85% Memory 70%
You decide the container needs more CPU.
Traditionally, changing the resource configuration meant creating a replacement Pod. For some workloads, that is perfectly acceptable. For others—stateful services, long-running processes, latency-sensitive applications, or batch workloads—a restart can be disruptive.
Kubernetes 1.33 changes this with In-Place Pod Resize.
In Kubernetes 1.33, In-Place Pod Vertical Scaling graduated to Beta and was enabled by default. It allows CPU and memory requests and limits for containers in a running Pod to be changed without necessarily recreating the Pod.
Important version note: In-Place Pod Resize became stable in Kubernetes 1.35. So this article focuses on what made Kubernetes 1.33 important, while noting the later GA status.
Why Was Pod Resizing Difficult Before?
Let's take a simple Pod:
apiVersion: v1 kind: Pod metadata: name: api-server spec: containers: - name: api image: nginx resources: requests: cpu: "500m" memory: "512Mi" limits: cpu: "1" memory: "1Gi"
Suppose the application starts receiving more traffic.
You want to change:
CPU request: 500m → 1 CPU Memory: 512Mi → 1Gi
Historically, resource changes were tied to Pod replacement.
That creates a lifecycle similar to:
Existing Pod | v Delete / replace | v New Pod | v New resource allocation | v Application starts again
For a stateless web application with several replicas, this may be barely noticeable.
For a long-running workload, it can be much more painful.
What Does In-Place Pod Resize Change?
The basic idea is simple:
Running Pod | | Change CPU/Memory | v /resize subresource | v Kubelet | v Update container resources
The Pod continues to exist.
Its resource configuration changes while it is running.
Kubernetes introduced the /resize subresource for this purpose. Kubernetes 1.33 documentation recommends using kubectl with --subresource=resize; kubectl 1.32 or later supports this option.
A Simple Example
Let's say our application starts with:
resources: requests: cpu: "500m" memory: "512Mi" limits: cpu: "1" memory: "1Gi"
After observing the workload, we decide it needs:
CPU request = 1 Memory = 1Gi
Instead of replacing the Pod, the resize operation updates its resource requirements.
For example:
kubectl patch pod api-server \ --subresource=resize \ --type=merge \ -p '{ "spec": { "containers": [{ "name": "api", "resources": { "requests": { "cpu": "1", "memory": "1Gi" }, "limits": { "cpu": "2", "memory": "2Gi" } } }] } }'
The important part is:
--subresource=resize
You are explicitly asking Kubernetes to resize the existing Pod rather than treating the operation as an ordinary Pod update.
But There Is an Important Detail
"In-place" does not always mean:
The container will never restart.
This is one of the most important things to understand.
Kubernetes allows you to define a resizePolicy for containers.
For example:
resizePolicy: - resourceName: cpu restartPolicy: NotRequired - resourceName: memory restartPolicy: RestartContainer
This tells Kubernetes that CPU resizing can happen without restarting the container, while a memory resize should restart that particular container.
Kubernetes 1.33 introduced this more mature resize behavior as part of the Beta implementation.
So the actual behavior can look like:
CPU resize | +----> Container continues running Memory resize | +----> Container may restart
That distinction is critical when designing production workloads.
What Happens Inside Kubernetes?
Let's look at the flow at a higher level.
User / Controller | v Pod resize request | v Kubernetes API | v Kubelet | +-------+-------+ | | v v Can resize? Cannot resize? | | v v Apply resources Deferred | | v v Container runtime Retry later
The kubelet is responsible for applying the resource change on the node.
If the requested resize cannot currently be satisfied, Kubernetes can defer the operation rather than blindly pretending it succeeded. The Pod status exposes conditions such as PodResizePending and PodResizeInProgress to communicate resize state.
What If the Node Doesn't Have Enough Resources?
This is where things get interesting.
Suppose:
Node capacity: CPU = 8 RAM = 32 GiB
The node is already heavily utilized.
You ask Kubernetes to increase a Pod from:
CPU = 1
to:
CPU = 4
But there isn't enough capacity available.
Kubernetes doesn't simply move the running Pod to another node as part of the resize operation.
The resize can become deferred.
Conceptually:
Resize requested | v Node has capacity? | +--+--+ | | Yes No | | v v Resize Deferred | v Retry
This is an important difference between horizontal scaling and in-place vertical scaling.
HPA vs In-Place Pod Resize
These two mechanisms solve different problems.
Horizontal scaling
HPA generally changes:
3 Pods → 10 Pods
Example:
HPA | +-------+-------+ | | | Pod Pod Pod | +---- more replicas
Vertical scaling
In-place resizing changes:
Pod resources
For example:
Before: CPU = 500m Memory = 512Mi After: CPU = 1 Memory = 1Gi
So:
Horizontal scaling | v More Pods Vertical scaling | v Bigger resource allocation for an existing Pod
They are complementary rather than competing technologies.
Why Is This Useful for Stateful Applications?
This is probably one of the most interesting use cases.
Imagine:
Stateful Application | v +-------------+ | Pod | +-------------+ | v Storage
If the application needs additional CPU or memory, recreating the Pod may introduce unnecessary disruption.
With in-place resizing, the resource allocation can potentially be adjusted while retaining the existing Pod.
This can be particularly attractive for:
- Stateful services
- Long-running workers
- Batch workloads
- Large JVM applications
- Latency-sensitive applications
- Pre-warmed services
Kubernetes itself highlights stateful workloads, batch jobs and workloads sensitive to restarts as important use cases.
A Very Practical Example: JVM Startup
Consider a Java application.
During startup:
CPU usage | 100| ███ | █████ | ███████ | █████████ | ███████████ |____________________ Time
The application may need substantial CPU during:
- Class loading
- JIT compilation
- Cache initialization
- Application initialization
But after startup:
CPU usage | | ███ | ███ | ██ | ██ |____________________
The workload may require much less CPU.
In-place resizing opens the door to a strategy like:
Application starts | v Higher CPU allocation | v Initialization complete | v Reduce CPU allocation | v Normal operating state
This is one of the more interesting possibilities of vertical scaling.
What Happened in Kubernetes 1.33?
The feature did not suddenly appear in 1.33.
The underlying work started earlier.
The feature was first introduced as alpha in Kubernetes 1.27.
Then in Kubernetes 1.33 it graduated to Beta and became enabled by default.
That was an important milestone because the feature had matured significantly.
Kubernetes 1.33 also introduced improvements around:
- Resize status
- Kubelet resource allocation
- Checkpointing
- Faster resize detection
- CRI integration
- Sidecar resizing
- Error reporting
The old status.resize approach was also deprecated in favor of Pod conditions such as PodResizePending and PodResizeInProgress.
Checking the Resize Status
After requesting a resize, don't simply assume it succeeded.
Inspect the Pod:
kubectl get pod api-server -o yaml
You can also inspect the container status:
kubectl get pod api-server \ -o jsonpath='{.status.containerStatuses[*].resources}'
The important concept is that Kubernetes distinguishes between the desired resources and the resources actually allocated to the running container.
Think of it as:
Desired resources | v "Please give me 2 CPU" Actual resources | v "Currently running with 1 CPU"
Until the resize is actually applied, those two states may differ.
The Production Trap: Don't Resize Blindly
This feature is powerful, but it shouldn't become an excuse to randomly change resource values in production.
Suppose you see:
CPU = 90%
and immediately increase:
500m → 4 CPU
You may have treated the symptom rather than the problem.
The application could actually be suffering from:
- A slow database
- A memory leak
- Excessive garbage collection
- Poor SQL queries
- Network latency
- Lock contention
- A traffic spike
- Inefficient code
So the correct workflow is still:
Observe | v Understand | v Identify bottleneck | v Resize if appropriate | v Measure again
Kubernetes gives you the capability.
It doesn't remove the need for engineering judgment.
In-Place Resize and Cost Optimization
This is where the feature becomes particularly interesting for cloud environments.
Imagine you have a workload that spends most of the day at:
CPU = 500m
but occasionally needs:
CPU = 2
Traditionally, you might over-provision the workload:
CPU request = 2
all day.
That can waste cluster capacity.
With dynamic vertical scaling, you can potentially move toward:
Normal workload | v 500m CPU | | traffic increases v 2 CPU | | traffic decreases v 500m CPU
The long-term goal is better resource utilization without unnecessarily disrupting workloads.
This is exactly the kind of problem where Kubernetes' horizontal and vertical scaling capabilities can complement each other.
Where VPA Fits In
This becomes even more interesting when we introduce Vertical Pod Autoscaler (VPA).
VPA analyzes workload resource usage and can recommend or apply different CPU and memory allocations.
Historically, VPA commonly relied on replacing Pods when resource changes were required.
Modern VPA versions have an InPlaceOrRecreate mode that can attempt an in-place resource update first and fall back to Pod replacement when necessary.
Conceptually:
VPA | v Resource recommendation | +--------+--------+ | | Can resize Cannot resize | | v v In-place resize Recreate Pod
That is a much more interesting architecture than simply manually changing CPU and memory values.
A Better Way to Think About Kubernetes Scaling
We can now look at Kubernetes scaling as three different dimensions.
Kubernetes Scaling | +---------------+---------------+ | | | v v v Horizontal Vertical Infrastructure Scaling Scaling Scaling | | | v v v More Pods Bigger Pods More Nodes | | | HPA In-place Resize Node Autoscaler / VPA
Each solves a different problem.
Horizontal
"I need more instances."
Vertical
"This instance needs more or fewer resources."
Infrastructure
"The cluster itself needs more capacity."
Understanding this distinction is much more valuable than simply memorizing Kubernetes commands.
Is In-Place Pod Resize Completely Disruption-Free?
Not necessarily.
This is probably the most important caveat.
"In-place" means the Pod itself doesn't need to be recreated for the resize operation.
It does not mean every resource change is guaranteed to happen without a container restart.
The behavior depends on:
- Resource being changed
-
resizePolicy - Container runtime support
- Node capacity
- Kubernetes version
- Workload configuration
For example, a container can specify:
resizePolicy: - resourceName: cpu restartPolicy: NotRequired
meaning CPU changes don't require a restart.
For memory, a different policy can be selected.
So always test the exact workload behavior before assuming a production resize will be completely seamless.
Kubernetes 1.33 vs Kubernetes 1.35
There is an important historical distinction if you're writing about this feature today.
Kubernetes 1.27 | v Alpha | v Kubernetes 1.33 | v Beta | v Kubernetes 1.35 | v Stable / GA
In Kubernetes 1.33, this was a Beta feature enabled by default.
By Kubernetes 1.35, In-Place Pod Resize graduated to Stable/GA.
So if you're deploying this today, don't stop your research at the 1.33 documentation. The current Kubernetes documentation identifies in-place container resource resizing as stable since 1.35.
When Should You Actually Use It?
I would consider in-place resizing when:
Good candidates
Stateful workloads Long-running workers Batch processing JVM workloads Latency-sensitive services Pre-warmed applications Workloads with predictable vertical scaling patterns
Be more careful with
Poorly understood applications Applications with memory instability Workloads with strict restart requirements Clusters with very limited node capacity Applications that haven't been tested with resource changes
The key is not:
"Kubernetes supports in-place resizing, so let's use it everywhere."
The better engineering question is:
"Does this workload benefit from changing resource capacity without recreating the Pod?"
My Production Approach
If I were introducing this into a production platform, I would take a gradual approach.
Step 1 — Measure
Collect:
CPU Memory Latency Request rate Restart count OOM events
Step 2 — Understand the workload
Determine whether the application is:
CPU-bound Memory-bound I/O-bound Dependency-bound
Step 3 — Test resize behavior
Test CPU and memory changes independently.
Step 4 — Define resize policies
Be explicit about whether a resource change can restart the container.
Step 5 — Monitor resize status
Don't assume a resize was applied just because the desired specification changed.
Step 6 — Introduce automation carefully
Only after understanding the workload should you consider VPA or other automation.
This keeps resource optimization evidence-driven rather than reactive.
Final Thoughts
Kubernetes is often described as a platform for scaling applications.
But scaling doesn't always mean:
3 Pods → 10 Pods
Sometimes the better answer is:
1 Pod | v More CPU | v More memory
And sometimes you want the opposite:
High workload | v Large resource allocation | v Workload decreases | v Smaller resource allocation
That is the real value of In-Place Pod Resizing.
Kubernetes 1.33 made the capability substantially more mature by moving it to Beta and enabling it by default. Kubernetes 1.35 later took it to Stable/GA.
For cloud engineers, platform engineers, and Kubernetes administrators, this is more than another Kubernetes feature.
It moves Kubernetes closer to a model where resource allocation can respond dynamically to the workload without always forcing the application through a restart cycle.
And that has implications for:
availability → performance → resource utilization → automation → cloud cost.