Kubernetes
Shahar Azulay • Mar 10, 2024

Kubernetes Statefulset: What it is, Components & Best Practices

Discover how StatefulSets work, when you should use them, and how to make the most of StatefulSets within your Kubernetes clusters.

Kubernetes Statefulset: What it is, Components & Best Practices
Shahar Azulay
Shahar Azulay
March 10, 2024
July 5, 2026
7
min read
Kubernetes

Last updated on: July 4, 2026

In general, Kubernetes treats Pods the same way you might treat someone forgettable whom you meet at a party: Once the party's over, you forget the person's name forever, and you move on with your life. In the same way, most Pods in Kubernetes – specifically, Pods that are launched as part of a Deployment – are gone forever from Kubernetes's mind once they shut down because Kubernetes does not identify them in a unique, persistent way.

But sometimes, you do need Kubernetes to treat each Pod in a unique way, and you want it to remember a Pod's identity even if the Pod shuts down and restarts. This is necessary if, for instance, you want to assign persistent volumes to Pods and need to ensure that those resources can persist even if Pods shut down and restart. Or, you may want to set up a specific networking configuration for one of your applications.

This is where StatefulSets come in. By running Pods using StatefulSets instead of a traditional Deployment, you tell Kubernetes that it needs to give each Pod a unique and persistent identity, which makes it easier to support certain use cases.

Keep reading for a breakdown of how StatefulSets work, when you should use them, and how to make the most of StatefulSets within your Kubernetes clusters.

What is a Kubernetes StatefulSet?

Event type Purpose
Deployment Run Pods without unique identities or other specific patterns.
DaemonSet Run Pods on a specific node or nodes.
StatefulSet Assign unique, persistent identities to Pods that remain intact if Pods are restarted.

In Kubernetes, a StatefulSet is a set of Pods that receive unique, persistent identities. (The Kubernetes developers like to say that the Pods' identities are "sticky.") This means that if Kubernetes stops and restarts the Pods, their identities remain the same. In addition, StatefulSets make it possible to control the order in which Pod replicas start and stop.

Configuring a persistent identity using StatefulSets is beneficial in situations where Pods need to access stateful resources, such as persistent volumes – hence the term StatefulSet.

Having persistent identities is the key characteristic that distinguishes StatefulSets from other workload models in Kubernetes, including DaemonSets and Deployments.

Kubernetes StatefulSet with headless service managing pods and persistent volumes.

ReplicaSet

StatefulSet vs. Deployment

A Kubernetes Deployment is a way of telling Kubernetes how to run and manage a set of Pods that don't require persistent identities or any other type of special configuration. (Notice here that we're referring to Deployments with a capital D; this is a specific type of object in Kubernetes, whereas "deploying" resources in general is a more generic term that folks don't always use when referring to Deployments specifically.) If you just want to run an application, and you have no need to associate it persistently with stateful storage, networking or other resources, a Deployment lets you do that.

Deployments are the simplest way to deploy applications in Kubernetes because they have the fewest configuration requirements. In addition, a Deployment leaves it up to Kubernetes to determine which nodes should host which Pods, and to reschedule Pods (which means stopping them and restarting them on a different node) whenever Kubernetes deems it necessary in order to balance performance or achieve stable resource availability. They're typically best for stateless applications, where identical pods can sit behind a load balancer without needing stable identities. Since running applications in an automated way across a distributed cluster of servers is the main purpose of Kubernetes, Deployments are important for admins who want to say, "Hey K8s, here's my app. Please go and run it."

For these reasons, Deployments are the most common means of running applications in Kubernetes. If you're new to Kubernetes, you'll probably want to master how Deployments work before learning about StatefulSets, which are more complicated.

But when it comes time to deploy resources that require a persistent state, you'll need to learn about StatefulSets, a Kubernetes API object used to manage stateful applications running as containerized applications.

StatefulSet vs. DaemonSet

A DaemonSet tells Kubernetes that certain nodes in a cluster should always host a given Pod or Pods. DaemonSets are commonly used to address requirements like the need to run a Kubernetes monitoring agent on each node (which isn't necessary if you leverage a framework like eBPF, which is a much more efficient and effective way to achieve Kubernetes observability than conventional agent-based monitoring, but we digress).

In contrast, a StatefulSet's purpose is to ensure that Pods have persistent identities so that they can be reliably mapped to the same resources even if the Pods stop and restart.

When to use StatefulSets

Here's a look at the main reasons why you'd want to use StatefulSets, and which Kubernetes benefits they offer.

Configuring stable storage

The most common use case for StatefulSets is deploying applications that require access to persistent or stable storage, such as databases and data stores.

StatefulSets are important for accessing persistent storage because having stable pod identifiers and a consistent pod identity makes it possible to associate Pods with a storage volume. Each Pod typically gets its own storage volume instead of reusing the same storage. If the identities of the Pods that need to access storage changed whenever the Pods restarted, you'd have to update your storage volumes' configurations as well with the new Pods' identities. That would be a huge pain – not to mention less secure, because the more often you're changing storage resource configurations, the more likely it is that you'll make a mistake that allows access to a workload that shouldn't be able to view your data.

Assigning unique network identifiers

Similarly, StatefulSets are useful for applications such as data stores where Pods need persistent storage and a stable network identity. For example, each Pod gets a unique network identity and predictable hostname, giving it stable DNS on a stable network. This network identity lets other components reach a specific pod reliably, and that identity stays the same if the Pod restarts.

Headless service managing MongoDB pods in a Kubernetes StatefulSet.

StatefulSets are important for accessing persistent storage because their pod identifiers let Kubernetes keep each Pod mapped to its storage volume, preserving a unique network identity at the same time. Each Pod should keep its own storage volume rather than reuse the same storage after restarts or rescheduling. Here again, the alternative solution would be to try to configure identities manually and update them whenever Pods restart, which would be a ton of work that no sane K8s admin wants to do.

Starting and stopping Pods in a certain order

StatefulSets are useful when each Pod needs a stable network identity, and they let you control the order in which replicas of a Pod start. You can also require a set of Pod replicas to terminate in a certain order, including in reverse order. This control helps maintain consistency for workloads where you need to ensure that one Pod is running before a new pod starts, or that a previous pod is ready before another one proceeds.

For example, if you're applying rolling updates to an application – meaning you want to update an application without any downtime – you can configure a StatefulSet such that there are multiple replicas for the Pods you want to update. Then, when you update the Pods, the StatefulSet controller will automatically ensure that the update to one Pod has successfully completed before it begins updating the next one. In practice, an updated pod must be Ready before the controller moves on, and .spec.minReadySeconds can delay that handoff until readiness has been sustained. Manual pod deletion can also trigger recreation behavior, while the controller still works through all the pods one at a time to preserve a stable network for internal communication.

StatefulSets Limitations

While StatefulSets are a powerful tool, they are subject to some limitations and drawbacks.

The biggest limitation of StatefulSets is that they make certain assumptions about how stateful resources are managed and configured. For example, they're designed only to work with stateful storage that is provisioned manually or via a PersistentVolume provisioner. If you operate persistent storage in Kubernetes using a different approach, you're likely to find it difficult to connect that storage to Pods using StatefulSets. Good storage management also depends on checking whether persistent volume claims bind correctly to available volumes, including matching capacity and access modes. If binding fails, verify the storage class because it determines what gets provisioned for each Pod.

Similarly, you have to set up a headless Service if you want to manage persistent network identities for Pods using StatefulSets. If you don't have a Service configured for this purpose, it will be challenging to work with network identities based on StatefulSets.

Another limitation is that although StatefulSets start Pods in order and terminate them in reverse order when they are rescheduled, this is not the case if you delete a StatefulSet entirely. During rolling updates, Kubernetes deletes and recreates each Pod one at a time, waiting for the new Pod to become ready before replacing the previous Pod so the set stays consistent. Setting .spec.minReadySeconds can help ensure a new Pod is stable before Kubernetes scales or proceeds to the next Pod.

In short, while StatefulSets give you a level of control over Pods that you would lack when using a standard Deployment, their flexibility is limited. In particular, they can be frustrating to work with if you have storage or network resources that are configured in an unusual way, which makes storage considerations especially important.

Components of a StatefulSet

The components of StatefulSets vary depending on what a given StatefulSet is intended to do. But in general, they include:

  • statefulset metadata and a statefulset object name that follows valid DNS label rules.
  • A Pod template with template metadata labels app and an identical container spec for each replica, even though each Pod keeps its own identity.
  • service metadata that supports the network identity and discovery used by the set.
  • Configuration data that defines resources that the StatefulSet controller should associate with the Pod. For example, if you want to associate persistent storage with a Pod, you'd define the configuration using a volumeClaimTemplate and set volume resources through requests. Storage checks should also confirm that Persistent Volume Claims bind correctly to Persistent Volumes. If storage does not attach as expected, verify the storage class and related storage management settings.

In the following section, we'll explore what these components look like in an actual StatefulSet example.

How to create a StatefulSet in Kubernetes

Now that you know all about how StatefulSets work, let's talk about how to create one.

As we mentioned in the preceding section, you basically need to define two things: how to run your Pods, and how to associate them with any stateful resources they should access.

To do this, you write YAML code, just as you would for a standard Kubernetes Deployment or Pod template. A StatefulSet is a statefulset object with metadata and spec sections. For example, here's code that creates a sample StatefulSet named example-statefulset and

sample StatefulSet (borrowed from the Kubernetes documentation) that assigns a persistent volume to an NGINX instance:

To use this StatefulSet, you'd save the code to a file (like example-statefulset.yaml), then apply it using the following command:

How to Debug a StatefulSet

If a StatefulSet behaves in an unexpected way – if some or all of the Pods fail to start, for example – you can debug it using the following steps. The same checks are also useful when troubleshooting other kubernetes workloads in the cluster.

List StatefulSet Pods

First, when troubleshooting Kubernetes workloads, you'll want to know which Pods are in the StatefulSet, since the statefulset manages pods with stable identities and ordered behavior. If you labeled them when creating the StatefulSet, you can list the Pods using a command like the following:

If you didn't label the Pods, you'll have to look at your YAML code manually to determine which Pods are in the StatefulSet.

Debug Pods

Once you know which Pods are in the StatefulSet, debug them one-by-one using standard Pod and container troubleshooting techniques, including:

  • Check Pod state to determine if any Pods failed to start. And remember that since StatefulSet Pods are ordered, an issue with one Pod may cause other Pods never to start.
  • Look at Pod exit codes and error codes to determine why Pods may have failed.
  • View operating system logs from nodes that host the Pods for additional context about failure events.
  • Try starting the containers defined for the Pods manually to make sure you can successfully pull the images and run containers based on them.
Kubernetes pod lifecycle phases from pending to succeeded or failed.

Step-by-step Pod initialization

If your Pods appear to operate normally when you run them individually but you still have issues with the StatefulSet, consider starting Pods within the StatefulSet one-by-one. You can do this by adding the following annotation to your StatefulSet configuration:

Then, redeploy the StatefulSet. Because of the annotation, Kubernetes will start the first Pod in the set, then pause before starting others. This allows you to validate manually that the first Pod has started successfully. If it has, you can tell Kubernetes to proceed with launching the next Pod in the set by running:

Be sure to replace pod-name with the name of the actual Pod you want to launch.

Proceed in a similar fashion by verifying that the second Pod is operating normally, then move on to the following Pod, and so on until you've debugged all Pods in the set. With any luck, you'll figure out which Pod is holding up the others from starting, then dive deeper to determine why the problematic Pod is not operating normally.

Deleting a StatefulSet as part of Troubleshooting

In the course of troubleshooting a StatefulSet, you may decide that you want to delete it entirely, and then restart from scratch.

You can do this using a kubectl delete command like the following:

Alternatively, you can specify the name of the YAML file you used to start the StatefulSet when deleting it:

After deleting the StatefulSet, you may restart it with a kubectl apply command.

StatefulSet best practices

To get the most out of StatefulSets, consider the following best practices:

  • Assign unique labels: Using unique, meaningful labels when creating a StatefulSet makes it easier to list the Pods associated with the StatefulSet and perform troubleshooting tasks.
  • Configure unique resources for each Pod: Rather than trying to share a persistent volume or other stateful resources between Pods, configure a different one for each Pod.
  • Use StatefulSets only when necessary: Avoid using StatefulSets when there is a simpler way to achieve your goals. For example, if you simply want to create replicas of a Pod, you can do so using a ReplicaSet, which is less complicated to configure and manage than a StatefulSet.
  • Avoid unusual configurations: As we mentioned above, StatefulSets are designed with the assumption that you manage Kubernetes resources in a traditional way – using PersistentVolume provisioners or headless Services, for example. If you are dealing with edge cases or bespoke configurations, StatefulSets may not work well, and you should probably standardize your configurations to make them look more like "classic" Kubernetes resources before creating StatefulSets.

StatefulSet Troubleshooting with groundcover

If you run into a problem with StatefulSets that you just can't sort out, groundcover has you covered. By continuously monitoring and observing every log, metric, and trace available from your Kubernetes cluster, groundcover detects performance anomalies, and then provides the deep context necessary to troubleshoot them quickly.

Dashboard panel in groundcover interface showing Prometheus data source options and time series graph.

But don't just take our word for it. See for yourself by requesting a demo.

Sometimes, each Pod is truly unique…which is why we love StatefulSets

In short, StatefulSets are your go-to solution in any scenario where you need to treat each Pod as its own special, persistent entity – in other words, when you want to assign a unique identity to the Pod and carefully control how Kubernetes manages it.

StatefulSets do create more complexity than standard Deployments, and you shouldn't use a StatefulSet unless you require the specific capabilities that it supports. Most stateless Pods are not special, and should not be part of a StatefulSet. But when your Pod needs some extra handholding, a StatefulSet is the way to give it the attention it requires.

Shahar Azulay
Shahar Azulay
 
CEO

8 min read |
Published on: Mar 10, 2024

Latest posts

Explore related posts

Sign up for Updates

Keep up with all things cloud-native observability.

We care about data. Check out our privacy policy.