Stateless vs. Stateful (The Real-World Architecture)
The Stateful Server Problem
Current design: Servers are both application AND database.
Each server:
- Runs application code
- Stores data locally
- Acts as database
This creates problems.
Problem 1: Resource Coupling 💰
Application servers need:
- Powerful CPU (processing logic)
- Large RAM (active requests)
- Fast network (many connections)
- Minimal disk (no data storage)
Database servers need:
- Moderate CPU (query processing)
- Large RAM (caching)
- Massive disk (data storage)
- Moderate network (fewer connections)
Combined server requirements:
- Best CPU + Best RAM + Best disk + Best network
- = Extremely expensive
Must over-provision every resource.
Problem 2: Deployment Coupling 🚀
Microsoft: 2,000+ deployments per day
Scenario: Deploy new code to Server A
During deployment:
- Server A's application updating
- Server A's data inaccessible (only Server A can access its data)
- Data unavailable during deployment
Impact:
- 2,000 deployments/day
- Servers constantly updating
- Data frequently unavailable
- Unacceptable user experience
Problem 3: Developer Complexity ðŸ§
Developers must:
- Track sharding logic
- Know which data lives where
- Manage data locality in code
- Handle cross-server queries
High cognitive overhead for business logic development.
The Solution: Decoupled Architecture 🎯
Separate application and database layers:
Clients → App Load Balancer → Application Servers (stateless)
↓
DB Load Balancer → Database Servers (stateful)Application Layer (Stateless)
Characteristics:
- No data storage
- Process requests only
- All data in database
Load balancing: Round robin
Why round robin works:
- All app servers identical
- Any server can handle any request
- No data locality concerns
Request flow:
- User request → Any app server (round robin)
- App server fetches data from database
- App server processes request
- App server returns response
No consistent hashing needed.
Database Layer (Stateful)
Characteristics:
- Stores all data
- Sharded using consistent hashing
- Managed by database team
Load balancing: Consistent hashing
Who implements:
- MySQL developers
- MongoDB developers
- Redis developers
- PostgreSQL developers
Application developers: Don't worry about it.
Benefits of Decoupling
1. Independent Scaling
Scale separately based on needs:
- App servers: Add more CPU/network capacity
- Database servers: Add more disk/storage capacity
- Optimize costs
2. Deployment Independence
Deploy application code freely:
- Update app servers 2,000 times/day
- Zero database downtime
- Zero data unavailability
- User experience unaffected
3. Developer Simplicity
Application developers see:
- "One giant database"
- No sharding logic in code
- Clean abstraction
Database handles:
- All data distribution
- Consistent hashing
- Server management
Clear separation of concerns.
4. Specialization
Database experts: Optimize data layer Application developers: Focus on business logic
Each team owns their domain.
Real-World Implementation
Application Load Balancer
Use: Round robin (or weighted round robin)
Configuration:
- AWS Elastic Load Balancer
- Nginx
- HAProxy
Setup: Simple, well-documented
Database Load Balancer
Use: Consistent hashing (built into databases)
Databases with native sharding:
- MongoDB (automatic)
- Redis Cluster (automatic)
- Cassandra (automatic)
SQL databases:
- PostgreSQL: No native sharding (use managed services)
- MySQL: No native sharding (use managed services)
Managed services add sharding:
- AWS RDS
- Google Cloud SQL
- Azure Database
Who Uses Consistent Hashing?
Application Developers: Rarely
Use cases:
- Stateless app servers → Round robin
- Let database handle distribution
- Focus on business logic
Database Developers: Always
Use cases:
- Build consistent hashing into database
- Manage sharding transparently
- Handle data distribution
DevOps Engineers: Sometimes
Use cases:
- Configure app load balancers (round robin)
- Set up database clusters (database handles sharding)
- May configure caching layers (consistent hashing)
Exception: Stateful Systems
When you need consistent hashing in application layer:
1. Caching Systems
- Redis cache clusters
- Memcached clusters
- Application-managed caching
2. Session Storage
- Distributed session stores
- Real-time collaboration tools
3. WebSocket Servers
- Long-lived connections
- User pinned to specific server
These require consistent hashing at application level.
Key Takeaways
- Stateful servers couple resources, deployment, and logic
- Decoupled architecture separates concerns
- Application layer: Stateless, uses round robin
- Database layer: Stateful, uses consistent hashing
- Application developers rarely implement consistent hashing
- Database developers implement it in database internals
- Exceptions exist: Caching, sessions, WebSockets