What Are maxSurge and maxUnavailable in a Kubernetes Deployment?

intermediate|deploymentsdevopssreCKACKAD
TL;DR

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:

  1. Service criticality: Mission-critical services should use maxUnavailable: 0.
  2. Available resources: If the cluster is tight on resources, keep maxSurge low.
  3. Rollout speed requirements: Larger values for both parameters speed up the rollout.
  4. Pod startup time: Slow-starting Pods benefit from higher maxSurge to 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

Can both maxSurge and maxUnavailable be zero?
No. Kubernetes rejects the configuration because the rollout could never make progress -- it cannot add extra Pods or remove existing ones.
What happens if you set maxSurge to 100%?
Kubernetes creates a full set of new Pods immediately (doubling the total), then terminates the old ones once the new set is Ready. This is effectively a blue-green deployment.
How do percentages round?
maxSurge rounds up (e.g., 25% of 3 replicas = 1). maxUnavailable rounds down (e.g., 25% of 3 replicas = 0, meaning all Pods must stay available).

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.

Related Questions