🎉 DevOps Interview Prep Bundle is live — 1000+ Q&A across 20 topicsGet it →
All Articles

What is a Kubernetes StatefulSet — Explained Simply

StatefulSets confuse most beginners. Here's a clear explanation of what they are, how they differ from Deployments, and when you actually need them.

DevOpsBoysMay 31, 20263 min read
Share:Tweet

Kubernetes has Deployments for stateless apps and StatefulSets for stateful apps. But what does "stateful" actually mean, and when do you need a StatefulSet?


The Core Difference

Deployment pods are interchangeable. If you have 3 Nginx pods, it doesn't matter which one handles a request. You can kill any of them and recreate it. They're identical.

StatefulSet pods have identity. If you have a 3-node MongoDB cluster, mongo-0 is the primary, mongo-1 and mongo-2 are replicas. You can't just swap them — each pod has a specific role and persistent data.


What StatefulSets Guarantee

1. Stable, Predictable Pod Names

Deployment pods:    app-x8f2a, app-k3m9p, app-q7n1r  (random)
StatefulSet pods:   db-0, db-1, db-2                  (ordered, stable)

When db-0 restarts, it comes back as db-0 — same name, same network identity.

2. Stable Network Identity (Headless Service)

Each pod gets a DNS name:

db-0.db-service.namespace.svc.cluster.local
db-1.db-service.namespace.svc.cluster.local
db-2.db-service.namespace.svc.cluster.local

This is critical for databases — replicas need to know the exact address of the primary.

3. Ordered, Graceful Scaling

Pods are created in order: db-0 first, then db-1, then db-2. Pods are deleted in reverse: db-2 first, then db-1, then db-0.

This ensures databases can initialize in the right order.

4. Persistent Storage Per Pod

Each pod gets its own PersistentVolume that follows it across restarts:

db-0 → PVC: data-db-0 (100GB)
db-1 → PVC: data-db-1 (100GB)
db-2 → PVC: data-db-2 (100GB)

If db-1 is rescheduled to a different node, it reconnects to data-db-1 — its data is preserved.


StatefulSet Example: PostgreSQL

yaml
apiVersion: v1
kind: Service
metadata:
  name: postgres
  labels:
    app: postgres
spec:
  clusterIP: None    # Headless service — required for StatefulSet
  selector:
    app: postgres
  ports:
    - port: 5432
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres
spec:
  serviceName: postgres    # Must match headless service
  replicas: 3
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
        - name: postgres
          image: postgres:16
          ports:
            - containerPort: 5432
          env:
            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: postgres-secret
                  key: password
          volumeMounts:
            - name: data
              mountPath: /var/lib/postgresql/data
  volumeClaimTemplates:    # Creates PVC for each pod automatically
    - metadata:
        name: data
      spec:
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 20Gi

After applying:

bash
kubectl get pods
# NAME         READY   STATUS
# postgres-0   1/1     Running
# postgres-1   1/1     Running  
# postgres-2   1/1     Running
 
kubectl get pvc
# NAME              STATUS   CAPACITY
# data-postgres-0   Bound    20Gi
# data-postgres-1   Bound    20Gi
# data-postgres-2   Bound    20Gi

Deployment vs StatefulSet Decision

QuestionIf Yes → Use
App stores data locally?StatefulSet
Pods need unique identities?StatefulSet
Pods need to discover each other by name?StatefulSet
App is completely stateless?Deployment
Pods are interchangeable?Deployment

Use StatefulSet for: Databases (PostgreSQL, MySQL, MongoDB, Redis clusters), message queues (Kafka, RabbitMQ), distributed systems (Zookeeper, etcd), Elasticsearch clusters.

Use Deployment for: Web servers, API services, background workers, anything that reads from external storage.


Common Mistakes

Using StatefulSet for stateless apps — unnecessary complexity. If your app doesn't need persistent storage or stable identity, use a Deployment.

Deleting a StatefulSet without deleting PVCs — PVCs survive StatefulSet deletion by default. Data stays around (which is usually what you want, but be aware).

Scaling down too fast — StatefulSets scale down in order. Scaling from 3 to 1 removes db-2 then db-1. Make sure your application handles this gracefully.


StatefulSets are for applications that care about their identity and data. When in doubt, if you're deploying a database or distributed system on Kubernetes, use a StatefulSet. For everything else, a Deployment is simpler and usually correct.

Practice StatefulSets and Persistent Volumes with hands-on labs at KodeKloud.

🔧

Today I Fixed

Short real fixes from production — posted daily

Browse fixes
Newsletter

Stay ahead of the curve

Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.

Related Articles

Comments