DEV Community

Syed Kashif Ali
Syed Kashif Ali

Posted on

🚀 Amazon EKS: Stateful vs Stateless Applications — Services, Deployments, StatefulSets & Persistent Storage

  1. Stateless application in EKS

A stateless application does not store important data inside the Pod.

Examples:

Nginx
React frontend
Node.js API
Python Flask API
Java Spring Boot API

If a Pod dies, Kubernetes can create a new Pod and the application continues working because there is no important state inside the old Pod.

Architecture
Internet
|
v
AWS Load Balancer
|
v
+------------------+
| Kubernetes |
| Service |
| ClusterIP |
+------------------+
/ | \
v v v
Pod-1 Pod-2 Pod-3
API API API
| | |
+--------+--------+
|
v
External DB
Amazon RDS / etc.
Example: Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 3

selector:
matchLabels:
app: nginx

template:
metadata:
labels:
app: nginx

spec:
  containers:
    - name: nginx
      image: nginx:1.27
      ports:
        - containerPort: 80
Enter fullscreen mode Exit fullscreen mode

Here Kubernetes manages 3 interchangeable Pods.

If nginx-abc dies:

Before:

nginx-abc
nginx-def
nginx-ghi

      ↓ Pod-abc crashes
Enter fullscreen mode Exit fullscreen mode

After:

nginx-new
nginx-def
nginx-ghi

The new Pod doesn't need the old Pod's identity or filesystem.

  1. Service for Stateless application

The Service provides a stable network endpoint for the changing Pods.

apiVersion: v1
kind: Service
metadata:
name: nginx-service

spec:
type: ClusterIP

selector:
app: nginx

ports:
- port: 80
targetPort: 80

The Service finds Pods using:

labels:
app: nginx

So:

Client
|
v
nginx-service:80
|
+----> nginx Pod 1
|
+----> nginx Pod 2
|
+----> nginx Pod 3

The Service provides load balancing across the matching Pods.

  1. Stateful application in EKS

A stateful application needs persistent identity and/or persistent storage.

Examples:

MySQL
PostgreSQL
MongoDB
Redis
Kafka
Elasticsearch

For example, imagine MySQL:

MySQL Pod
|
+---- Database files
+---- Users
+---- Orders
+---- Transactions

If the Pod disappears, you cannot simply create an empty new MySQL Pod.

You need the data to survive.

That's where:

StatefulSet
PersistentVolumeClaim
PersistentVolume
EBS/EFS
Headless Service

come into the picture.

  1. StatefulSet

For Kubernetes-native stateful workloads, we commonly use a StatefulSet instead of a Deployment.

Example:

apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql

spec:
serviceName: mysql
replicas: 1

selector:
matchLabels:
app: mysql

template:
metadata:
labels:
app: mysql

spec:
  containers:
    - name: mysql
      image: mysql:8.0

      env:
        - name: MYSQL_ROOT_PASSWORD
          value: "mypassword"

      ports:
        - containerPort: 3306

      volumeMounts:
        - name: mysql-data
          mountPath: /var/lib/mysql
Enter fullscreen mode Exit fullscreen mode

volumeClaimTemplates:
- metadata:
name: mysql-data

  spec:
    accessModes:
      - ReadWriteOnce

    resources:
      requests:
        storage: 20Gi
Enter fullscreen mode Exit fullscreen mode

The important part is:

volumeClaimTemplates:

Kubernetes creates a PVC for the StatefulSet.

  1. What happens in EKS?

Suppose you have:

StatefulSet
|
v
mysql-0
|
v
PVC
|
v
PV
|
v
AWS EBS Volume

For example:

mysql-0
|
+---- mysql-data-mysql-0
|
v
EBS 20 GB

The MySQL data is stored on the persistent volume rather than only inside the container.

  1. What happens if MySQL Pod crashes?

This is the important part.

Initially:

mysql-0
|
v
EBS Volume
|
+---- customer data
+---- orders
+---- database

Suppose:

mysql-0
X
CRASH

StatefulSet recreates:

mysql-0
|
v
Existing PVC
|
v
Existing EBS
|
+---- customer data
+---- orders
+---- database

So the new Pod can mount the existing persistent storage.

The Pod name remains:

mysql-0

This stable identity is one of the major differences from a normal Deployment.

  1. StatefulSet vs Deployment Feature Deployment StatefulSet Used for Stateless apps Stateful apps Pod identity Temporary Stable Pod names Random-ish suffix Ordered names Example api-7d9f... mysql-0 Persistent storage Optional Common PVC Usually separate Can use volumeClaimTemplates Scaling Easy Ordered Pod replacement Interchangeable Identity preserved Example Node.js API MySQL
  2. Stateful Service

Stateful applications often use a Headless Service.

Example:

apiVersion: v1
kind: Service
metadata:
name: mysql

spec:
clusterIP: None

selector:
app: mysql

ports:
- port: 3306
targetPort: 3306

Notice:

clusterIP: None

This makes it a Headless Service.

Instead of giving one virtual IP, Kubernetes DNS can resolve individual StatefulSet Pods.

For example:

mysql-0.mysql.default.svc.cluster.local

If you had:

mysql-0
mysql-1
mysql-2

they can have stable DNS identities:

mysql-0.mysql
mysql-1.mysql
mysql-2.mysql

  1. Why StatefulSet needs Service?

Consider a database cluster:

             mysql-service
                   |
      +------------+------------+
      |            |            |
      v            v            v
   mysql-0      mysql-1      mysql-2
      |            |            |
     PVC          PVC          PVC
      |            |            |
     EBS          EBS          EBS
Enter fullscreen mode Exit fullscreen mode

The Service provides stable networking.

The StatefulSet provides:

stable Pod identity
ordered deployment
ordered termination
persistent storage association

  1. Stateless EKS example — Node.js API

Imagine your ecommerce application:

                Internet
                   |
                   v
             AWS ALB
                   |
                   v
            Kubernetes Service
                   |
      +------------+------------+
      |            |            |
      v            v            v
   API Pod      API Pod      API Pod
      |            |            |
      +------------+------------+
                   |
                   v
                Amazon RDS
                   |
                   v
                MySQL
Enter fullscreen mode Exit fullscreen mode

Your Node.js API is stateless.

Why?

Because:

User
|
v
API Pod
|
v
RDS

The API doesn't permanently store the user's orders inside its own filesystem.

If:

API Pod 1 → crashes

Kubernetes creates:

API Pod 4

and the application continues.

  1. Stateful EKS example — MySQL

Now imagine MySQL running inside EKS:

         MySQL Service
               |
               v
            mysql-0
               |
               v
              PVC
               |
               v
          EBS Volume
               |
               v
         Database Data
Enter fullscreen mode Exit fullscreen mode

If:

mysql-0 → crashes

Kubernetes recreates:

mysql-0

and attaches the persistent storage.

  1. Very important: EKS + RDS

In production, you generally don't need to run MySQL yourself inside EKS if you can use Amazon RDS/Aurora.

A common architecture is:

                Internet
                   |
                   v
                 ALB
                   |
                   v
          Kubernetes Service
                   |
      +------------+------------+
      |            |            |
      v            v            v
   API Pod      API Pod      API Pod
      |            |            |
      +------------+------------+
                   |
                   v
             Amazon RDS
              MySQL/Postgres
Enter fullscreen mode Exit fullscreen mode

Here:

EKS

Runs your stateless application:

Frontend
Backend
API
Microservices
RDS

Runs your stateful database:

MySQL
PostgreSQL

AWS handles much of the database infrastructure for you.

This is usually preferable to running production MySQL directly inside EKS unless you have a specific reason to do so.

  1. Easy way to remember Stateless Deployment ↓ Pods ↓ Service ↓ External database

Pods are replaceable.

Pod dies
↓
New Pod
↓
Continue
Stateful
StatefulSet
↓
Pod
↓
PVC
↓
PV
↓
EBS/EFS

Pod identity and data persistence matter.

Pod dies
↓
Same identity
↓
Same persistent storage
↓
Continue with data
Interview answer

  • If an interviewer asks "What is the difference between StatefulSet and Deployment in EKS?", you can say:

Deployment is mainly used for stateless applications where Pods are interchangeable. StatefulSet is used for stateful applications that require stable Pod identity, predictable naming, and persistent storage. In EKS, a Deployment might run Node.js API replicas behind a Service, while a StatefulSet could run MySQL with PVCs backed by EBS. For production databases, however, I would generally prefer Amazon RDS/Aurora rather than managing the database inside EKS.

Top comments (0)