StatefulSet exists for workloads where replicas are not interchangeable. Databases, brokers, and clustered systems often need stable names, stable storage, and predictable ordering. That is the problem StatefulSet is built to solve.

When to use StatefulSet

  • each replica needs its own persistent volume
  • stable Pod identity matters
  • startup or shutdown order matters
  • peer discovery depends on fixed DNS names

If the workload is disposable and replicas are interchangeable, a Deployment is usually simpler.

StatefulSet vs Deployment

Use Deployment when:

  • replicas are stateless
  • rollouts can treat all Pods as identical
  • storage is external or disposable

Use StatefulSet when:

  • each replica has identity and data you care about
  • ordered rollout is safer
  • direct Pod addressing is part of the topology

This controller boundary matters a lot. Many storage and database problems come from choosing Deployment for a workload that really wants StatefulSet semantics.

What StatefulSet gives you

  • stable Pod names like mysql-0, mysql-1
  • one PVC per replica
  • ordered startup and shutdown by default
  • stable DNS through a headless Service

It does not give you backups, failover policy, or a magical data recovery story. Those are still your job.

Headless Service is part of the pattern

StatefulSets usually depend on a headless Service:

apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  clusterIP: None
  selector:
    app: mysql
  ports:
    - port: 3306
      targetPort: 3306

This gives each Pod a stable DNS identity such as mysql-0.mysql.default.svc.cluster.local.

Core snippet

spec:
  serviceName: mysql
  replicas: 3
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 10Gi

Ordered behavior and why it matters

StatefulSet scales up in ordinal order and usually scales down from the highest ordinal first. This makes rollouts and recovery slower than Deployment, but safer for systems that care about leader/follower relationships, initialization order, or quorum behavior.

This extra slowness is not a bug. It is the cost of keeping state safer.

Stable DNS and client access

Stateful systems often need two traffic patterns:

  • load-balanced access through a Service
  • direct access to specific replicas through stable Pod DNS names

For example, writes may go to a leader, while reads may go to followers. StatefulSet makes this easier because replica identity is stable.

Storage behavior

Each replica gets its own claim. That is why ReadWriteOnce is common: each Pod owns its own volume.

This is also why PVC count and storage cost scale with replica count. Three replicas often means three separate volumes, not one shared pool.

If you want to understand that storage chain end to end, read kubernetes-quickstart-pv-pvc.md for the workload-facing side and kubernetes-quickstart-storageclass.md for the provisioner and policy side behind dynamic provisioning.

Rolling updates and partitions

By default, updates move from the highest ordinal down. You can also use partitions to update only part of the set:

updateStrategy:
  type: RollingUpdate
  rollingUpdate:
    partition: 1

That keeps lower ordinals on the old version and lets you stage risk more carefully.

Pod management policy

The default ordered behavior is often the right choice. You can use podManagementPolicy: Parallel when the app can tolerate out-of-order startup, but that is a workload decision, not just a speed setting.

Common StatefulSet pitfalls

PVC is not bound

Now the StatefulSet cannot make progress because the Pod cannot mount its storage.

Readiness is too strict

This can block ordered rollout for the whole set.

People assume PVC means backup

It does not. PVC means persistence, not recovery strategy.

Deployment-style thinking leaks in

Deleting Pods casually, reusing shared volumes, or expecting all replicas to behave identically often creates trouble.

A practical troubleshooting sequence

kubectl get pods
kubectl get pvc
kubectl describe pod <pod-name>
kubectl describe pvc <claim-name>
kubectl get events -A

Then ask:

  1. Is the right ordinal blocked?
  2. Is storage bound and mounted?
  3. Is readiness preventing ordered progress?
  4. Is the app expecting a startup sequence or peer topology that is not being met?

Recovery mindset

StatefulSet gives you stable identity, not automatic resilience. You still need:

  • backups
  • restore drills
  • realistic failover expectations
  • migration planning
  • capacity planning per replica

This is the part many tutorials skip, but it is where real operations begin.

FAQ

Q: Why not just use a Deployment with a PVC? A: Because a Deployment treats replicas as interchangeable. StatefulSet is built for stable identity and one-volume-per-replica behavior.

Q: Why are StatefulSet rollouts slower? A: Because ordered startup, readiness, and per-replica storage make safety more important than speed.

Q: If I delete a StatefulSet, does that delete the data too? A: Not necessarily. PVCs often remain, but the exact behavior depends on how storage and reclaim policy are configured.

Next reading

  • Continue with kubernetes-quickstart-headless-service.md for stable identity and DNS.
  • Read the MySQL quickstart pages for concrete stateful examples.
  • If you are planning production safety, continue into backup and rollout tips.

Wrap-up

StatefulSet is where Kubernetes starts asking you to think like an operator, not just a deployer. Stable identity and stable storage are useful, but they come with recovery, sequencing, and lifecycle responsibility.

References