Courses 0%
02
Software Architecture Patterns · Chapter 2 of 42

Stateful && Stateless Services

Akhil
Akhil Sharma
10 min

Stateful vs Stateless Services

🎭Stateless vs Stateful Services - The Memory Question

🎯 The Forgetful vs Remembering Server

Scenario: You're talking to a customer service agent.

Forgetful Agent (Stateless):

You: "I'd like to order a pizza" Agent: "Sure! What would you like?"

You: "Large pepperoni please" Agent: "Sorry, what were you ordering?"

You: "A PIZZA! Large pepperoni!" Agent: "Oh okay. What size?"

You: "I JUST SAID LARGE!" Agent: "Right, and what toppings?"

You: 😤😤😤

Remembering Agent (Stateful):

You: "I'd like to order a pizza"

Agent: "Sure! What would you like?" [Writes on notepad: Pizza order]

You: "Large pepperoni please"

Agent: "Got it! Large pepperoni pizza." [Writes: Large, pepperoni]

You: "Actually, add mushrooms"

Agent: "Sure, adding mushrooms to your large pepperoni!" [Updates notepad: + mushrooms]

You: 😊

This is the difference between Stateless and Stateful!


🎨 Understanding State

What is "State"? State = Information that needs to be remembered between interactions

STATELESS SERVICE

═══════════════════════════════════════

No memory of previous requests Each request is independent

img1
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

STATEFUL SERVICE

═══════════════════════════════════════

Remembers information between requests Maintains session data

img2


🍕 Real-World Example: Pizza Website

Let's see both approaches for the same app:

Stateful Approach (Old School)

USER'S SHOPPING JOURNEY:

═══════════════════════════════════════

Step 1: User logs in

Browser → Server 1

Server 1: Creates session

[Memory: SessionID-123

Step 2: User adds pizza

Browser → Server 1 (same server!)

Server 1: Looks up session in memory

[SessionID-123 User: Alice Cart: [Pepperoni Pizza]]

Step 3: User adds drink

Browser → Server 1 (MUST be same server!)

Server 1: Updates session

[SessionID-123

🚨 PROBLEM: What if Server 1 crashes? OR: Load balancer sends to Server 2?

Browser → Server 2

Server 2: "SessionID-123? Never heard of it!" [No memory of Alice!]

Result

img3
:

Cart is empty! User has to start over! 😡

Stateless Approach (Modern)

USER'S SHOPPING JOURNEY:

═══════════════════════════════════════

Step 1: User logs in

Browser → Server 1

Server 1: Creates session token (JWT)

Stores session in Redis (shared database)

Redis: [SessionID-123 → User: Alice, Cart: empty]

Browser receives cookie: SessionID-123

Step 2: User adds pizza

Browser → Server 2 (different server! doesn't matter!)

Server 2: Reads SessionID-123 from cookie Looks up in Redis

Redis: SessionID-123 → User: Alice, [blocked]

Cart: [Pepperoni Pizza]]

Server 2: Updates Redis

Browser: Still has same cookie

Step 3: User adds drink

Browser → Server 3 (yet another server!)

Server 3: Reads SessionID-123 from cookie

Looks up in Redis Updates Redis

Redis: SessionID-123 → User: Alice, [blocked]

Cart: [Pepperoni, Coke]]

✅ ANY SERVER CAN HANDLE ANY REQUEST!

✅ Server crashes? No problem!

✅ Load balancing works perfectly!

Visual representation:

img4


🎮 Interactive Comparison: ATM Analogy

Scenario: You're withdrawing money from an ATM.

Stateful ATM (Bad Design):

You at ATM #1: "I want to withdraw $100" ATM #1: "Okay, I remember you!" [Stores in local memory: Balance = $900]

Next day at ATM #2: "What's my balance?" ATM #2: "I don't know you. Your balance is $1000" (Doesn't know about yesterday's withdrawal!)

Next day at ATM #1 again: "What's my balance?" ATM #1: "Your balance is $900" (Still remembers!)

Different ATMs = Different answers = 😱

Stateless ATM (Good Design):

You at ANY ATM: "I want to withdraw $100" ATM: [Checks central bank database] "Current balance: $1000" [Updates central database: $900] "Here's your $100"

You at ANY other ATM: "What's my balance?" ATM: [Checks central bank database] "Your balance is $900"

Every ATM sees the same data! 😊

The ATM itself is stateless The bank's database holds the state


🚨 Common Misconception: "Stateless = No Data Storage"

You might think: "Stateless means we can't store user data at all!"

The Truth: Stateless means the SERVER doesn't store it. The DATA exists elsewhere!

❌ WRONG UNDERSTANDING:

═══════════════════════════════════

"Stateless = No user data anywhere"

img5

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✅ CORRECT UNDERSTANDING:

═══════════════════════════════════

"

img6

Stateless = Server doesn't hold state"

Key insight: Stateless servers + Shared storage = Best of both worlds!


📊 Real-World Architecture Comparison

🏢 TRADITIONAL STATEFUL (2000s)

═══════════════════════════════════════════

img7
Problems:

❌ User `1 must always hit Server 1`

❌ Can't easily add more servers

❌ Server restart = lost sessions

❌ Complex load balancing

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

🚀 MODERN STATELESS (2020s)

═══════════════════════════════════════════

img8

Benefits:

✅ Add/remove servers anytime

✅ Server crashes? No problem!

✅ True horizontal scaling

✅ Simple load balancing

✅ Easy deployment/updates


💡 When to Use Each Approach

✅ USE STATELESS WHEN:

═══════════════════════════════════════

  1. Horizontal scaling needed Example: Web applications, APIs

  2. High availability required Example: E-commerce, banking

  3. Cloud/containerized deployment Example: Kubernetes, microservices

  4. Multiple servers expected Example: Anything beyond toy projects

  5. You want simple operations Example: Easy deploys, restarts

Real-world: 95% of modern web apps!

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

⚠️ USE STATEFUL WHEN:

═══════════════════════════════════════

  1. Performance critical (local memory is fast)

    Example: Gaming servers (player positions)

  2. Complex distributed state is overkill

    Example: Simple internal tools

  3. State is truly server-specific

    Example: WebSocket connections (connection IS tied to server)

  4. Legacy systems

    Example: Migrating old apps

Real-world: 5% of modern web apps


🎯 Design Challenge: Convert Stateful to Stateless

Problem: You have a stateful chat application. Make it stateless!

Original Stateful Design:

Server stores in memory:

  • Active chat connections

  • Unread message counts

  • Typing indicators

  • User online status

Problem: Can't scale! Each user tied to one server.

Your Stateless Solution:

STEP 1: Move connections elsewhere

═══════════════════════════════════════

WebSocket connections stay on servers (This part MUST be stateful)

But use Redis to track which user is on which server: Redis: { "user123": "server-3", "user456": "server-1" }

STEP 2: Move data to shared stores

═══════════════════════════════════════

Redis:

  • Unread counts: "user123:unread" → 5

  • Online status: "user123:online" → true

  • Typing: "room:456:typing" → ["user123"]

STEP 3: Message routing

═══════════════════════════════════════

Use message queue (RabbitMQ/Kafka):

User A (on Server 1) sends message to User B (on Server 2):

Server 1 → Queue → Server 2

↓ [Database] (permanent storage)

FINAL ARCHITECTURE:

img9
) ══════════════════════════════════════

Now: Servers can be added/removed! Users reconnect to any server!


🎪 The Complete Comparison

img10

Winner for modern apps: STATELESS! 🏆

Exception: When performance trumps everything


🔑 Key Takeaways: Stateless vs Stateful

📝 CORE CONCEPTS:

═══════════════════════════════════════

STATE = Information between requests

STATELESS:

• Server doesn't remember you

• Data stored externally (Redis, DB)

• Any server handles any request

• Scales horizontally easily

• Modern best practice

STATEFUL:

• Server remembers you in memory

• Fast but doesn't scale

• User tied to specific server

• Harder to maintain

• Avoid unless necessary

🎯 ONE SENTENCE SUMMARY: "Build stateless servers that store data in shared external systems so any server can handle any request."

🔄 THE PATTERN: Server (stateless) → External Store (state)

Examples:

Web Server → Redis (sessions)

Web Server → Database (user data)

Web Server → S3 (files)

Web Server → Cache (temporary data)


Chapter complete!

Course Complete!

You've finished all 42 chapters of

System Design Indermediate

Browse courses
Up next Synchronous and Asynchronous Communication Patterns
Continue