What Are maxSurge and maxUnavailable in a Kubernetes Deployment?
maxSurge controls how many extra Pods can exist above the desired replica count during an update. maxUnavailable controls how many Pods can be down simultaneously. Together they control the speed, resource usage, and safety of a rolling update.
Detailed Answer
The maxSurge and maxUnavailable parameters are the two knobs that control how a RollingUpdate behaves. They determine the pace of the rollout, how many resources are consumed during the transition, and how much availability risk you accept.
Definitions
- maxSurge: The maximum number of Pods that can exist above the desired replica count during an update. Accepts an absolute number or a percentage.
- maxUnavailable: The maximum number of Pods that can be unavailable (not Ready) during an update. Accepts an absolute number or a percentage.
Basic Configuration
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 4
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web-app
image: web-app:2.0
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
With replicas: 4, maxSurge: 1, maxUnavailable: 1:
- Maximum total Pods: 4 + 1 = 5
- Minimum available Pods: 4 - 1 = 3
Step-by-Step Rollout Example
Starting state: 4 old Pods running.
| Step | Old Pods | New Pods | Total | Available | |------|----------|----------|-------|-----------| | 0 | 4 | 0 | 4 | 4 | | 1 | 4 | 1 (starting) | 5 | 4 | | 2 | 3 | 1 (ready) | 4 | 4 | | 3 | 3 | 2 (1 starting) | 5 | 4 | | 4 | 2 | 2 (ready) | 4 | 4 | | 5 | 2 | 3 (1 starting) | 5 | 4 | | 6 | 1 | 3 (ready) | 4 | 4 | | 7 | 1 | 4 (1 starting) | 5 | 4 | | 8 | 0 | 4 (ready) | 4 | 4 |
At every step, at least 3 Pods are available and never more than 5 total exist.
Common Configurations
Maximum Safety (Zero Downtime)
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
- Never removes an old Pod until a new one is Ready.
- Slowest rollout but zero risk of reduced capacity.
- Requires extra resources for the surge Pod.
- Best for production-critical services.
Maximum Speed
rollingUpdate:
maxSurge: "50%"
maxUnavailable: "50%"
- Creates many new Pods simultaneously.
- Removes many old Pods simultaneously.
- Fastest rollout but significant capacity fluctuation.
- Best for development and testing environments.
Resource-Constrained
rollingUpdate:
maxSurge: 0
maxUnavailable: 1
- No extra Pods are created (no additional resource usage).
- One old Pod is removed before a new one is started.
- Rollout is slow and capacity drops temporarily.
- Best when the cluster has no spare capacity for extra Pods.
Percentage vs. Absolute Values
Both parameters accept percentages or integers:
# Percentage-based
rollingUpdate:
maxSurge: "25%"
maxUnavailable: "25%"
# Absolute number
rollingUpdate:
maxSurge: 2
maxUnavailable: 1
Rounding Rules
Percentages are calculated against replicas with specific rounding:
- maxSurge rounds UP (favors creating more Pods).
- maxUnavailable rounds DOWN (favors keeping more Pods available).
| Replicas | Setting | maxSurge (25%) | maxUnavailable (25%) | |----------|---------|----------------|----------------------| | 4 | 25% | ceil(1.0) = 1 | floor(1.0) = 1 | | 10 | 25% | ceil(2.5) = 3 | floor(2.5) = 2 | | 3 | 25% | ceil(0.75) = 1 | floor(0.75) = 0 | | 1 | 25% | ceil(0.25) = 1 | floor(0.25) = 0 |
Notice that with 3 replicas and 25%, maxUnavailable rounds to 0. This means all Pods must remain available, making the rollout very conservative.
The Zero-Zero Trap
rollingUpdate:
maxSurge: 0
maxUnavailable: 0
Kubernetes rejects this configuration with a validation error:
Invalid value: intstr.IntOrString{Type:0, IntVal:0, StrVal:""}: may not be 0 when
maxSurge is 0
With both set to 0, the controller cannot create new Pods (no surge allowed) and cannot delete old Pods (no unavailability allowed). The rollout would be deadlocked.
Impact on Rollout Duration
With replicas: 10:
| maxSurge | maxUnavailable | Effective Parallelism | Relative Speed | |----------|----------------|----------------------|----------------| | 1 | 0 | 1 at a time | Slowest | | 1 | 1 | 2 at a time | Moderate | | 3 | 2 | 5 at a time | Fast | | "100%" | "100%" | All at once | Instant (like Recreate) |
Choosing Values for Production
Consider these factors:
- Service criticality: Mission-critical services should use
maxUnavailable: 0. - Available resources: If the cluster is tight on resources, keep
maxSurgelow. - Rollout speed requirements: Larger values for both parameters speed up the rollout.
- Pod startup time: Slow-starting Pods benefit from higher
maxSurgeto overlap startup phases.
A balanced production configuration:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 10
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: "25%" # Up to 13 Pods during rollout
maxUnavailable: 0 # All 10 Pods always available
template:
spec:
containers:
- name: web-app
image: web-app:2.0
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
Summary
maxSurge and maxUnavailable give you precise control over the tradeoff between rollout speed, resource usage, and availability. For production workloads, maxUnavailable: 0 with a small maxSurge provides the safest rollout. For development environments, higher values speed up deployments. Understanding the rounding rules and the relationship between these two parameters is essential for tuning rollouts to your specific needs.
Why Interviewers Ask This
These parameters directly affect deployment safety and speed. Interviewers ask about them to see if you can tune rollout behavior for different environments and risk tolerances.
Common Follow-Up Questions
Key Takeaways
- maxSurge controls the ceiling -- how many extra Pods are allowed.
- maxUnavailable controls the floor -- how many Pods can be down.
- For zero-downtime deployments, set maxUnavailable to 0.