Script Valley
System Design: APIs, Caching & Scalability
Scalability PatternsLesson 3.5

Stateless vs stateful services: design trade-offs

stateless service definition, stateful service risks, session externalization, sticky sessions as anti-pattern, idempotent operations, twelve-factor app principles

Stateless vs stateful services: design trade-offs

Stateless vs stateful services

The Core Distinction

A stateless service treats every request independently — no memory of previous requests in the process. A stateful service maintains context between requests, usually in memory. Stateless services scale horizontally with zero coordination. Stateful services require sticky routing or state synchronization.

Externalizing State

Move state to a system designed for it:

  • Sessions → Redis
  • Uploads → S3 or object storage
  • Queued jobs → Redis Queue, SQS, or RabbitMQ
  • WebSocket presence → Redis Pub/Sub
# Any server instance can subscribe to any channel
redis.subscribe('chat:room:42', (message) => {
  // broadcast to local WS clients in this room
});

Idempotency

Stateless design pairs with idempotency. If a client retries a request, the server should produce the same result without side effects. Use idempotency keys for writes:

POST /payments
Idempotency-Key: uuid-abc-123

Store processed idempotency keys in Redis with a TTL. If the same key arrives again, return the cached response. This enables safe client-side retries without double charges or duplicate records.