Stateless vs Stateful: Key Differences
Stateless systems treat each request independently; stateful systems maintain context.
Stateless and stateful
Stateless and stateful are fundamental architectural concepts in web development and distributed systems. They describe whether a system remembers previous interactions between requests. The choice between them shapes your API design, authentication strategy, infrastructure requirements, and how easily your application can scale.
What Is a Stateless System
In a stateless system, each request is completely self-contained and independent. The server does not retain any memory of previous requests from the same client. Every request must include all the information the server needs to process it, and the server treats every incoming request as if it is the first one it has ever received from that client.
HTTP was designed from the beginning to be stateless. Each HTTP request carries its own method, URL, headers, and body. The server reads what it needs from the current request alone. It does not consult any stored context from previous requests to formulate a response. This stateless design was a deliberate architectural choice that makes HTTP simple, predictable, and trivially scalable: any server that can handle HTTP can handle any individual request without needing to know what happened before it.
Request 1:
GET /api/orders HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...
Accept: application/json
→ Server processes this request independently. No prior context needed.
Request 2 (same client, different server instance):
GET /api/orders/42 HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...
Accept: application/json
→ Any server can handle this. It carries its own auth token.
→ Server does not need to remember Request 1 to process Request 2.
What Is a Stateful System
In a stateful system, the server retains information about the client between requests. After the first interaction, the server stores context such as who the user is, what they have done, or what their current state is, and uses that stored context to interpret subsequent requests from the same client. The server and client maintain an ongoing relationship across multiple exchanges.
A traditional web session is the classic example. After a user logs in, the server creates a session record, stores data about the user in memory or a database, and assigns a session ID. The browser stores this session ID in a cookie and sends it with every subsequent request. The server looks up the session ID to retrieve the stored context and uses it to understand who is making the request and what they are allowed to do. The server is maintaining state on behalf of the client between requests.
Request 1 (login):
POST /login
Body: { username: "alice", password: "..." }
→ Server verifies credentials
→ Server creates session: sessions["abc123"] = { userId: 42, role: "admin" }
→ Server responds: Set-Cookie: session_id=abc123
Request 2 (same client):
GET /dashboard
Cookie: session_id=abc123
→ Server looks up sessions["abc123"] → finds userId: 42, role: "admin"
→ Server uses stored state to personalise the response
→ This server MUST have access to the session store to handle this request
Stateless vs Stateful: Full Comparison
| Feature | Stateless | Stateful |
|---|---|---|
| Memory of Past Requests | None. Each request is treated as if it is the first. | Yes. Context is stored server-side in memory, cache, or a database. |
| Scalability | Excellent. Any server instance can handle any request because no shared state is required. | More complex. Sessions may pin clients to specific server instances unless a shared session store is used. |
| Fault Tolerance | High. A server restart has no effect on clients because no session data is lost. | Lower. A server restart can invalidate in-memory sessions unless sessions are stored externally in Redis or a database. |
| Authentication Mechanism | A self-contained token such as a JWT is sent with every request and verified cryptographically without a database lookup. | A session ID is sent with each request and the server looks up the corresponding session data in its store. |
| Request Size | Larger. Each request must carry all necessary context including authentication credentials. | Smaller. Only a short session identifier needs to be sent, as the server retrieves the rest from its store. |
| Server Resources | Lower. No session data needs to be stored or managed on the server side. | Higher. Each active session occupies memory or database storage that must be maintained and expired. |
| Revocation | Harder. A JWT cannot be invalidated before it expires without a token blacklist or short expiry times. | Easier. Deleting a session record immediately terminates that client's access regardless of what token they hold. |
| Client Responsibility | Client must securely store and transmit the token on every request. | Client stores only a session ID, which is a short opaque reference with no sensitive data embedded. |
| Examples | REST APIs, HTTP protocol, DNS, CDN delivery, JWT-authenticated services | Traditional web application sessions, FTP connections, multiplayer game servers, database connection pools |
How REST APIs Use Statelessness
Statelessness is one of the six core architectural constraints of REST, defined by Roy Fielding in his doctoral dissertation. A REST API that violates statelessness, by storing client context between requests on the server, is technically not RESTful. The stateless constraint exists because it is what makes REST APIs horizontally scalable and resilient by design.
In a properly stateless REST API, every request must stand entirely on its own. This means the following in practice.
- Authentication is included on every request: The client sends a Bearer token in the Authorization header on every request. The server verifies the token cryptographically without consulting any session store. Any server instance that knows the signing key can verify any token.
- Pagination and filtering parameters are included on every request: A request for page 3 of a result set must include
?page=3in the URL. The server does not remember that the client previously requested pages 1 and 2. - No server-side session is maintained: The server allocates no resources to track individual clients between requests. Once a response is sent, the server discards all context about that request.
- Any server in the pool can handle any request: Because no client-specific state is stored on any individual server, a load balancer can route each request to whichever server is least busy without any sticky session configuration.
Stateful Systems and Sticky Sessions
The primary infrastructure challenge of stateful systems at scale is ensuring that every request from a given client reaches a server that has access to that client's session data. In a single-server deployment this is trivial, but in a multi-server deployment it requires one of two solutions.
- Sticky sessions (session affinity): The load balancer is configured to always route requests from the same client to the same server instance. This is simple to set up but reduces the effectiveness of load balancing and creates a single point of failure: if the assigned server goes down, all its sessions are lost and those clients must log in again.
- Shared external session store: All server instances store and retrieve session data from a shared external store such as Redis or Memcached. Any server can handle any request because they all read from and write to the same session store. This approach scales better and tolerates server failures without session loss, but adds an external dependency and a network round-trip for every session lookup.
STATELESS (JWT tokens):
Client → Load Balancer → Server A ✓ (verifies token locally, no lookup needed)
Client → Load Balancer → Server B ✓ (same token, same verification, works fine)
Client → Load Balancer → Server C ✓ (any server works, no coordination needed)
STATEFUL (server-side sessions without shared store):
Client → Load Balancer → Server A ✓ (session stored in Server A's memory)
Client → Load Balancer → Server B ✗ (Server B has no session data, request fails)
Client → Load Balancer → Server A ✓ (sticky sessions required for reliability)
STATEFUL (server-side sessions with shared Redis store):
Client → Load Balancer → Server A ✓ (reads session from Redis)
Client → Load Balancer → Server B ✓ (reads same session from Redis)
Client → Load Balancer → Server C ✓ (works, but adds Redis dependency)
When to Choose Each Approach
| Use Case | Recommended Approach | Reason |
|---|---|---|
| REST API consumed by mobile or SPA clients | Stateless (JWT) | Scales horizontally without infrastructure coordination. Any server handles any request. |
| Traditional server-rendered web application | Stateful (server session) | Simpler implementation, easier revocation, session data never leaves the server. |
| Real-time chat or multiplayer game server | Stateful | Persistent connection context is essential. The server must maintain state about the ongoing connection. |
| Microservices architecture | Stateless | Each service must be independently scalable and deployable without coordination of shared session state. |
| High-security application requiring instant revocation | Stateful or short-lived JWT with blacklist | Server-side sessions can be deleted immediately. JWTs are valid until expiry unless a revocation mechanism is added. |
| Public API with third-party developers | Stateless (API keys or OAuth tokens) | Third-party developers cannot participate in server-side session management. |
| Simple internal admin tool | Stateful | Simplicity and ease of revocation outweigh the scalability benefits of statelessness for low-traffic internal tools. |
Frequently Asked Questions
- Is HTTP really stateless if cookies exist?
Yes. The HTTP protocol itself is stateless by specification. Cookies and sessions are mechanisms layered on top of HTTP at the application level to simulate statefulness within an inherently stateless protocol. The protocol sends each request independently with no built-in memory of previous requests. A cookie is simply an HTTP header that the browser sends with every matching request. What the server does with that cookie, whether it looks up a session or ignores it, is application logic sitting above the protocol layer. The protocol remains stateless regardless of how applications use it. - Can a stateless API carry state information?
Yes, and this is a common point of confusion. A JWT token is stateless from the server's perspective because the server does not store it, but the token itself contains encoded state information such as the user's ID, role, and token expiry. The token is self-contained, meaning the server can verify it and extract the information it carries without consulting any external store. This is different from server-side statefulness where the client sends an opaque identifier and the server looks up the associated data. The distinction is about where the state is stored and managed, not whether state information exists at all. - Is stateless always better than stateful?
No. Statelessness provides clear benefits for scalability and fault tolerance, but it comes with trade-offs that make stateful approaches preferable in certain contexts. Stateless tokens like JWTs cannot be immediately revoked without additional infrastructure such as a token blacklist, which reintroduces some statefulness. Stateless requests carry more data per round trip because all context must be included each time. For simple applications with a single server, an admin panel with a small number of concurrent users, or any system where instant session revocation is a security requirement, stateful server sessions may be the simpler, more appropriate choice. - What happens to stateful sessions when a server restarts?
If sessions are stored in the server's memory, a restart destroys all active sessions and every logged-in user is immediately signed out. This is a significant reliability concern in production environments. The standard solutions are to store sessions in an external persistent store such as Redis or a database rather than in application memory, so they survive server restarts. Some applications also use signed cookies that store session data directly in the browser rather than on the server, which survives server restarts entirely since no server-side storage is involved. - How does statelessness relate to microservices?
Statelessness is essentially a prerequisite for effective microservice architecture. In a microservices system, individual services are deployed, scaled, and restarted independently. If services maintained state about individual clients, orchestrating a restart or scaling event would require careful coordination to avoid losing client sessions or routing requests to the wrong instance. By designing each service to be stateless, each request carries all the context the service needs, any instance of the service can handle any request, and the system scales horizontally by simply adding more instances. Any state that genuinely needs to persist between requests, such as user data or application data, is stored in dedicated databases or caches that are themselves designed for durability and replication.
Conclusion
Stateless and stateful architectures represent two fundamental approaches to managing context in networked systems, each with clear strengths suited to different requirements. Stateless systems are easier to scale horizontally, more resilient to server failures, and simpler to reason about because every request is independent, but they place more responsibility on clients to carry context and make immediate revocation harder. Stateful systems are simpler to implement for user sessions, offer instant revocation by deleting a record, and require clients to store only a short identifier, but they require careful infrastructure planning to scale across multiple server instances without sticky sessions or a shared session store. Most modern APIs and microservices adopt a stateless design using JWT tokens or similar self-contained credentials, while traditional server-rendered web applications continue to benefit from the simplicity of stateful sessions. See also JWT, session vs token authentication, cookies vs sessions, and load balancing to understand how these concepts apply in practice.
