Kubernetes Deployment vs StatefulSet: Key Differences and Use Cases

Kubernetes Deployment vs StatefulSet explained: Learn the key differences between stateless and stateful workloads, pod identity, storage, scaling, and best practices. Understand when to use each to ensure high availability and data consistency in Kubernetes clusters.

Table of contents
Key Takeaways

1. Learn the difference between Kubernetes Deployment and StatefulSet, and how they handle stateless vs stateful workloads.

2. Understand how Deployments manage scaling and rolling updates, while StatefulSets ensure stable pod identity and persistent storage.

3. Discover when to use each to prevent downtime, configuration drift, and potential data loss in Kubernetes clusters.

4. Compare storage behavior, scaling, and rollout strategies of Deployments vs StatefulSets with an easy-to-read tables.

5. Follow hands-on YAML examples to create both Deployments and StatefulSets in Kubernetes.

What is a Kubernetes Deployment?

The Deployment object in Kubernetes is generally used for stateless applications. It ensures that application pods are always running and up to date.

Before we talk about Deployments, let us understand ReplicaSets.

  • A ReplicaSet ensures that a pod is running at all times.
  • If a pod is deleted, the ReplicaSet recreates it automatically.
  • However, a ReplicaSet alone does not automatically update pod configurations if the template changes.

A Deployment extends this functionality:

  • Ensures the pod configuration always matches the deployment manifest.
  • Supports rolling updates and rollbacks.
  • Allows defining rollout strategies to control updates.

Deployment Use Cases

  • Stateless web applications (Nginx, Tomcat, Apache)
  • Services that do not need a stable network identity or persistent storage
  • Applications that require frequent rolling updates

1. Deployments, ReplicaSet and Pods interactions
[Fig 1] Deployments, ReplicaSet and Pods interactions

Deployments help you to achieve the following:

  • To rollout ReplicaSet - It will create your pods in the background. You can check the status of the rollout to see if it has succeeded or not.
  • Declare the new state of the pods - You can update the PodTemplateSpec of the deployment manifest. A new replicaset is created, and the deployment moves the pods from the old replicaset to the new one at a controlled rate. Each new replicaset will now have the updated revision of the deployment.
  • Rollback to earlier deployment revision - If due to some circumstance, the current state doesn’t turn out to be stable, then the deployment can be rolled back to an earlier deployment revision.

What doesn’t Deployment provide?

  • It doesn’t provide an identifier to pods.
  • It doesn’t provide storage for pods, hence it is used for only stateless applications (the ones that don’t care which network is being used, and don’t need any permanent storage. For e.g., Web Servers such as Apache, Nginx, Tomcat.

Deployment Hands-on

Let’s understand the entire process and what happens behind the scenes with some hands-on examples.

First, let us create a deployment using a YAML file. In the below manifest, we are creating a deployment with 5 replicas, i.e, 5 pods of the same application, and we use the nginx image.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 5
  selector:
    matchLabels:
      app: nginx
  strategy: {}
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        name: nginx

Upon applying this file, there are a few things that will happen.

  • The deployment will be created
  • The deployment will create a ReplicaSet
  • The ReplicaSet will create 5 pods
Note: In the below images, I have used an aliased kubectl to k. If you wish to set the name, you can run the below command
echo “alias k=kubectl” >> ~/.bashrc
source ~/.bashrc
2. Create a Deployment
[Fig 2] Create a Deployment

Now, when it comes to updating the deployment, a similar set of steps will be followed. First, the deployment will create a new ReplicaSet which will have the updated configuration. Depending on the defined rollout strategy, the old replicaset will start to scale down, while the new ReplicaSet gradually scales up the number of replicas. Eventually, once the old ReplicaSet has scaled down to zero, it will be deleted, and all the running pods will contain the new configuration. Let’s see this in action.

Update the existing deployment to use the busybox image. You can use the deploy command to edit the deployment

kubectl edit deployment nginx

You can observe that a new ReplicaSet has been created and the old one is gradually being scaled down. You can check the pod manifest, and you will notice that it is using the new busybox image.

3. Edit the image of a Deployment
[Fig 3] Edit the image of a Deployment

What is a Kubernetes StatefulSet?

StatefulSets are designed for stateful applications like databases that need:

  • Persistent storage
  • Stable pod identity
  • Ordered, predictable scaling

Key differences from Deployments:

  • Pods have unique identifiers (e.g., pod-0, pod-1).
  • Each pod can have its own PersistentVolumeClaim (PVC).
  • Provides stable DNS and network identity via a headless service.

StatefulSet Use Cases

  • Databases (MongoDB, MySQL, PostgreSQL)
  • Applications requiring a stable network identity
  • Workloads with persistent state or leader-follower architecture
4. StatefulSets
[Fig 4] StatefulSets

To create a StatefulSet, you first need to create a headless service. As the pods have unique identifiers, StatefulSets also provide each pod with a stable, unique network identity, which is crucial for stateful applications like databases that need consistent, stateful connections. Unlike a normal service, a headless service does not provide a load-balancing ClusterIP. Instead, Kubernetes creates unique DNS addresses for each Stateful pod. For example, if the name of the service is mongo-svc for pods created by the mongodb StatefulSet, the DNS entries would be

  • mongodb-0.mongo-svc
  • mongodb-1.mongo.svc
  • mongodb-2.mongo.svc

You can create the headless service by using the following YAML

apiVersion: v1
kind: Service
metadata:
 name: mongo-svc
 labels:
   app: mongodb
spec:
 ports:
 - port: 27017
   name: db
 clusterIP: None
 selector:
   app: mongodb

For now, this service will not target any pods as the StatefulSet has not yet been created. Notice that in the above manifest, the selector is defined as app: mongodb. When creating the StatefulSet, you need to ensure that the pods have the same label.

You can create the StatefulSet with the following YAML

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mongodb
spec:
  selector:
    matchLabels:
      app: mongo
  serviceName: "mongo-svc"
  replicas: 3
  template:
    metadata:
      labels:
        app: mongo
    spec:
      containers:
      - name: nginx
        image: registry.k8s.io/nginx-slim:0.24
        ports:
        - containerPort: 27017
          name: mongodb
        volumeMounts:
        - name: www
          mountPath: /usr/share/mongo/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "standard"
      resources:
        requests:
          storage: 1Gi

In the above YAML file, a storage class is defined, which means that the persistent volumes and PVCs will be dynamically created and bound to the stateful pods. However, if there is no storage class, or if it is of a local storage type, you will need to manually create the PVs and PVCs and ensure that they are bound before creating the StatefulSet.

If the StatefulSet is created successfully, you will be able to see the pods with the unique identifiers as such

5. StatefulSets Deployed in cluster
[Fig 5] StatefulSets Deployed in cluster

Kubernetes Deployment vs StatefulSet: Key Differences

FeatureDeploymentStatefulSet
Use CaseStateless appsStateful apps (databases)
Pod IdentityRandom hashStable, unique identifiers
Storage BehaviorShared/ephemeral volumesDedicated persistent volumes
ScalingEasy, parallel scalingOrdered, controlled scaling
Rollout / RollbackSupportedLimited and ordered
Network IdentityDynamicStable via headless service

The difference in attaching volumes for storage in a Deployment and StatefulSet

  • Deployments: It is used for “stateless applications”. The volume (PVC) is shared across the pods. Since there is no data in the volume that is shared, it leads to data exposure concerns.
  • StatefulSet: It is used for “stateful applications”. The PVC will have information stored in it, and this leads to the sharing of information across all the pods.

Using PVC across Deployments and StatefulSets

PVC can be used across deployments and statefulsets with the help of Access Modes. There are 3 Access Modes, namely

  • ReadWriteOnce: Mount the volume as read-write by a single node.
  • ReadOnlyMany: Mount the volume as read-only to many nodes.
  • ReadWriteMany: Mount the volume as read-write by many nodes.

When to Use Deployment vs StatefulSet

  • Use Deployments for:
    • Web servers, APIs, and stateless microservices
    • Applications that don’t rely on persistent storage
  • Use StatefulSets for:
    • Databases and message queues (MongoDB, RabbitMQ)
    • Applications needing persistent state or stable network identity

Conclusion

Choosing between a Kubernetes Deployment vs StatefulSet depends on your application’s nature:

  • Stateless workloads → Deployments for easy scaling and rolling updates
  • Stateful workloads → StatefulSets for stable identity and persistent storage

Understanding these differences ensures cluster stability, data safety, and seamless scaling in Kubernetes.

FAQ

What is the difference between Deployment and StatefulSet in Kubernetes?

A Kubernetes Deployment manages stateless applications, ensuring that pods are always running and up to date, but it does not preserve pod identity or state. StatefulSet, on the other hand, is used for stateful applications, where each pod has a stable, unique identity and persistent storage, essential for databases and similar workloads.

When should I use StatefulSet instead of Deployment in Kubernetes?

Use StatefulSet when your application requires persistent storage, ordered pod creation, stable network identities, or strict control over pod lifecycle—such as in the case of databases like MongoDB or PostgreSQL. For stateless services like web servers, Deployments are more appropriate.

Can I use Persistent Volume Claims (PVCs) with both Deployment and StatefulSet?

Yes, but they behave differently. Deployments typically share a single PVC across all pods, requiring ReadWriteMany access mode. StatefulSets create a unique PVC per pod using VolumeClaimTemplates, generally using ReadWriteOnce mode to ensure data isolation and consistency for stateful workloads.

What happens to data if a pod is deleted in Deployment vs StatefulSet?

In a Deployment, deleting a pod usually results in data loss unless external storage is used, as pods are stateless. In a StatefulSet, each pod has its own persistent volume, so even if a pod is deleted, its data remains intact and is restored when the pod is recreated.

Related articles

Related articles