Topic 1.3
StatefulSets vs Deployments
In one line
A Deployment's pods are fully interchangeable clones; a StatefulSet's pods each get a stable, unique identity and their own persistent storage — exactly what a real database or any stateful workload actually needs.
Think of it like this
A Deployment's pods are like identical rental cars from a large fleet — any one is as good as any other, and swapping one out for a fresh one changes nothing. A StatefulSet's pods are like assigned, named lockers — locker #1 is always locker #1, always keeps its own specific contents, and swapping it for an empty locker #4 would genuinely lose something important.
Key ideas
- 01
A Deployment's pods are fully INTERCHANGEABLE — they share one identical template, get random names and IPs, and any pod can be replaced by any other with zero meaningful difference. This works perfectly for STATELESS applications (a web server, an API) that keep no important data of their own between requests.
- 02
A STATEFULSET gives each of its pods a STABLE, PREDICTABLE identity: pods are named sequentially (
my-db-0,my-db-1,my-db-2, never randomly), created and scaled up/down in strict ORDER (0 before 1 before 2), and each one gets its OWN dedicated persistent storage that follows that specific pod even if it's rescheduled to a different node. - 03
This matters enormously for genuinely STATEFUL workloads — a database where each replica holds its own distinct data and needs to always come back to the SAME storage volume it had before, or a distributed system where nodes need stable network identities to find and coordinate with each other (like Kafka brokers or a database's replication setup, both covered in later, more advanced material).
- 04
Each StatefulSet pod also gets a stable, predictable DNS name (
my-db-0.my-db-headless-svc, using a special 'headless' Service, distinct from the load-balancing Service from Topic 1.2) — genuinely important for stateful systems where OTHER nodes need to reliably address one SPECIFIC replica by name, not just 'any healthy replica,' which is exactly what a normal load-balancing Service provides instead. - 05
The practical rule of thumb: reach for a Deployment by default for anything stateless (which is the overwhelming majority of typical application workloads) and reach for a StatefulSet specifically when you have a genuine need for stable per-pod identity and per-pod persistent storage — using a StatefulSet for a stateless app adds real complexity (ordered rollout, per-pod storage) for zero actual benefit.
Code & diagrams
Interchangeable clones versus stable, individually-identified members.
Note volumeClaimTemplates — each pod gets its OWN dedicated storage, unlike a Deployment.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: my-db
spec:
serviceName: my-db-headless # a headless Service, for stable per-pod DNS
replicas: 3
selector:
matchLabels:
app: my-db
template:
metadata:
labels:
app: my-db
spec:
containers:
- name: my-db
image: postgres:16
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
volumeClaimTemplates: # each pod gets its OWN PVC — see Phase 2
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10GiExplain it without notes
Why would using a Deployment (instead of a StatefulSet) for a real multi-node database be a genuine problem?
What does 'stable identity' actually mean for a StatefulSet's pods, in concrete terms?
Practice
Create the example StatefulSet and observe with kubectl get pods that the pods are named my-db-0, my-db-1, my-db-2 — sequential, not random.
Delete one specific StatefulSet pod (e.g. my-db-1) and confirm its replacement comes back with the SAME name and reconnects to the SAME persistent volume, unlike a Deployment's pods.
Trade-offs
- ↔
A StatefulSet's ordered, identity-preserving behavior is exactly what genuinely stateful workloads need, but it comes at the cost of slower, more careful scaling and rollout (strictly one pod at a time, in order) compared to a Deployment's freely parallel scaling — for a workload that's genuinely stateless, this ordering constraint is pure, unnecessary overhead, which is exactly why Deployments remain the correct default for the majority of workloads.
Done when you can
I can explain the difference between a Deployment's interchangeable pods and a StatefulSet's stable-identity pods.
I understand why databases and similar stateful workloads need a StatefulSet, not a Deployment.
I know StatefulSet pods each get their own persistent volume and a predictable name and DNS entry.