Choosing Kubernetes Workload Types: Deployment vs StatefulSet vs DaemonSet vs Job

Choosing Kubernetes Workload Types#

Kubernetes provides several workload controllers, each designed for a specific class of application behavior. Choosing the wrong one leads to data loss, unnecessary complexity, or workloads that fight the platform instead of leveraging it. This guide walks through the decision criteria and tradeoffs for each type.

The Workload Types at a Glance#

Workload Type Lifecycle Pod Identity Scaling Model Storage Model Typical Use
Deployment Long-running Interchangeable Horizontal replicas Shared or none Web servers, APIs, stateless microservices
StatefulSet Long-running Stable, ordered Ordered horizontal Per-pod persistent Databases, message queues, distributed consensus
DaemonSet Long-running One per node Tied to node count Node-local Log collectors, monitoring agents, network plugins
Job Run to completion Disposable Parallel completions Ephemeral Batch processing, migrations, one-time tasks
CronJob Scheduled Disposable Per-schedule run Ephemeral Periodic backups, cleanup, scheduled reports
ReplicaSet Long-running Interchangeable Horizontal replicas Shared or none Almost never used directly

Decision Criteria#

The choice comes down to four questions:

Kubernetes Deployment Strategies: Rolling, Blue-Green, and Canary

Kubernetes Deployment Strategies#

Every deployment strategy answers the same question: how do you replace running pods with new ones without breaking things for users? The answer depends on your tolerance for downtime, risk appetite, and infrastructure complexity.

Rolling Update (Default)#

Rolling updates replace pods incrementally. Kubernetes creates new pods before killing old ones, keeping the service available throughout. This is the default strategy for Deployments.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-api
spec:
  replicas: 4
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  minReadySeconds: 10
  selector:
    matchLabels:
      app: web-api
  template:
    metadata:
      labels:
        app: web-api
    spec:
      containers:
      - name: web-api
        image: web-api:2.1.0
        readinessProbe:
          httpGet:
            path: /healthz
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5

Key parameters: