The Tradeoffs Between Stateful and Stateless Software Design

June 8, 2026

☕️ Support Us
Your support will help us to continue to provide quality content.👉 Buy Me a Coffee

Whether you work on the frontend or backend, software design often comes down to one question: should this be stateful or stateless? This also comes up frequently in interviews. An interviewer might ask, "Is XX stateful or stateless by design? Why?" The XX can be many different technologies. In authentication, for example, you might compare stateful session-based auth with stateless token-based auth. In communication, you might compare stateful WebSockets with stateless HTTP.

To answer that question well, or to make the right technical decision at work, you need to understand the tradeoffs behind both choices. In this article, we will use concrete examples to explain the differences and tradeoffs between stateful and stateless design.

Stateful and Stateless Design Through Authentication

In a previous article, "What Are the Differences Between Common Tokens Used in Login and Authentication?", we discussed different authentication approaches. One point was that in web development during the 1990s, session-based authentication was the mainstream approach. Session-based authentication requires the server to manage sessions. The challenge is that when traffic grows and you want to horizontally scale by adding more servers, you need to decide how those sessions should be handled.

One solution is to make sure requests from the same user always go to the same server. This is commonly known as sticky sessions. But this approach makes a user's state depend on a specific server. If that server goes down and the session has not been synchronized to shared storage, the user's request can be routed to another server, but it may fail because the new server does not have the original session state. This creates a potential single point of failure.

For example, imagine an ecommerce checkout flow. A user adds items to a shopping cart, and the session state is stored on server A. During checkout, server A goes down, so the load balancer routes the request to backup server B. Since server B does not have the relevant session, the cart may be emptied or the request may fail. This is a simplified example of cart state being temporarily stored on a single machine. In real ecommerce systems, cart state is usually placed in shared storage, a database, or a cache to avoid relying only on one server's memory.

Another example is an online form where you want to preserve progress. After the user fills out part of the form, the state is temporarily stored in the session on server A. If server A goes down, and the user later comes back to continue the remaining steps, the submission may be routed to a different server. The previously entered data is then lost, forcing the user to start over. That creates a poor user experience.

From the perspective of state, this kind of session-based design is called stateful. But why exactly is it stateful? Let's define the term more precisely.

What Is the Difference Between Stateful and Stateless?

In software design, stateful means that a component, such as a server, keeps information needed for future interactions. In the examples above, that information could be shopping cart data or temporary form progress. Stateless means the component itself does not carry that information. When you interact with it, you need to provide all the information required for that interaction.

There is a similar analogy in everyday life. Before medical information systems became widespread, visiting a clinic was closer to a stateful experience. Most people went to a nearby clinic, and the doctor kept paper medical records containing the patient's history. If someone visited frequently, the doctor might even remember them well enough to start the consultation without pulling out the records. In that situation, the consultation could be fast. But if the patient switched to a different clinic, the new doctor would not have the old records, making diagnosis more difficult.

In modern healthcare, many systems have moved toward electronic medical records and cross-institution data exchange. Conceptually, this moves state from a single clinic's paper records to a shared system that other medical providers can query. That makes the design closer to stateless. No matter where the patient receives care, the records are available through a shared system rather than being locked inside one clinic. Even if the patient changes clinics or doctors, the new doctor can quickly understand the patient's history.

Returning to authentication, the previous token article also discussed token-based authentication, which uses self-contained tokens such as JWTs. This design makes authentication closer to stateless because the server does not necessarily need to store a session for every user. It can validate the token's signature and contents instead. In other words, every request carries enough information for any server to process it independently.

In practice, the server generates an encoded token and sends it to the client. The token already contains the information needed for authentication. Each later request includes that token. The server does not need to keep session state; it only needs to validate the token. Since the state is no longer bound to a specific server, server A can fail and server B can still handle the request.

The Tradeoffs Between Stateful and Stateless

With those examples in mind, let's return to the tradeoffs. From the medical record and authentication examples, we can see that stateful design can be faster, but it is harder to scale and can lose state during failures. Stateless design is easier to scale, and a single machine failure is less likely to cause state loss.

But at a deeper level, stateless does not mean there is no state at all. It means the protocol or service node itself does not keep state that is required to understand the next request based on the previous one. Put differently, stateless design does not remove state; it moves state management somewhere else. In token-based authentication, the state is moved into the token held by the client. In the medical record example, digital records move state from a local clinic to a shared cloud-backed system.

So when we discuss stateful versus stateless design, we are not really asking whether state exists. We are asking where the state should live and whether the server should store it. Let's use another common example to make this idea clearer.

Comparing HTTP and WebSocket State Design

In frontend-backend communication, HTTP is one of the most common application-layer protocols, and HTTP is stateless by design. HTTP was proposed by Tim Berners-Lee, the inventor of the World Wide Web and a Turing Award winner. At the time, hardware was far more limited than it is today. Server RAM was measured in megabytes, which made it very constrained. If HTTP had been designed as stateful, servers would have needed to store large amounts of client state, quickly consuming memory and making large-scale operation difficult. From the perspective of scaling the web globally, a stateful design would have been much harder to make work.

Because HTTP is stateless, every HTTP request is independent from the server's perspective. After a request is handled, the server no longer needs to remember information related to that request. It can release those resources and move on to the next request, which helps request handling scale effectively.

HTTP's stateless design works well for scaling one-way requests from clients. But when communication needs to become bidirectional, statelessness forces developers to find additional solutions. If you use HTTP for bidirectional communication, such as real-time messaging, the server does not remember connection state. The client often has to keep sending requests through polling, which can create a lot of waste.

That is why the industry later adopted WebSocket, a stateful protocol where the server keeps the connection itself and related context.

WebSocket's stateful design reduces waste. After the connection is established, both sides can continuously send data over the same long-lived connection. This avoids the extra headers, request-response round trips, and idle polling costs caused by repeatedly sending short-polling HTTP requests. With an active connection, data transfer between client and server can also be faster. The tradeoff is that the server must manage connection state, so at larger scale it will eventually hit scaling bottlenecks.

HTTP and WebSocket are not simply good or bad. The important question is where each one fits. For ordinary client requests, not maintaining state on the server scales well and is a better fit for most scenarios. Maintaining state on the server limits scalability, but it can reduce waste and lower latency, which makes it more suitable for real-time bidirectional communication.


Support ExplainThis

If you found this content valuable, please consider supporting our work with a one-time donation of whatever amount feels right to you through this Buy Me a Coffee page.

Creating in-depth technical content takes significant time. Your support helps us continue producing high-quality educational content accessible to everyone.

☕️ Support Us
Your support will help us to continue to provide quality content.👉 Buy Me a Coffee