by • July 5, 2023
The difference between stateful and stateless applications is essential when developing APIs. However, if you’re not a developer who’s working with stateful and stateless systems, you might not fully understand these concepts. More importantly, you may not know why stateless REST APIs are so essential to building scalable web applications?
Here are the key takeaways to know about stateful vs. stateless apps:
Table of Contents
Sign up for our free 14 day hosted trial to learn how.
A stateful application saves client session data (i.e., information about previous client requests, login/authentication status, or “state” data). For some stateful systems, this data is saved on the server where the application runs. In enterprise architectures, state data is saved within the caching tier, and not on the application server itself.
A stateful app still has a back-end database, but it uses its saved state data as context when processing subsequent requests from the same client.
In a traditional stateful web application, a user’s state is maintained because the server is doing all of the work associated with recreating a web page whenever the user clicks on a link, submits a button, etc.
Having this information available on the server or in the caching tier speeds up processing as long as the server is powerful enough to handle the traffic.
When an application is stateful, it relies on saved client session data to process new transactions. A stateful app still uses a database for back-end storage, but it also uses the server where the application runs to store data from previous interactions. This client session data (state data) allows the app to process subsequent transactions in the context of preceding ones.
Traditional web apps are stateful applications that use remote sessions to maintain their state. This involves keeping all of the session data on the server. According to Roy T. Fielding’s seminal work that introduced REST to the world: “The remote session style is a variant of client-server that attempts to minimize the complexity, or maximize the reuse, of the client components rather than the server component. Each client initiates a session on the server and then invokes a series of services on the server, finally exiting the session. Application state is kept entirely on the server.”
Here’s a simple analogy: A stateful app is similar to what happens when you visit your local bank — where you’ve been a client for many years. Everyone at the bank recognizes you, so you don’t have to show them your ID before making a transaction. The bank also maintains the records of your previous transactions in-house.
On your end, you don’t have to save any “state” information. You can simply show up, ask some questions about your balance, and tell them the transactions to make. This system is fast and efficient as long as the bank can handle the number of clients who are trying to make transactions at a single point in time.
One example of a stateful application is a stateful web service that stores client authentication data on the server, labeling clients as having a “connected” or “disconnected” state. It also stores information about previous requests from the same clients.
It uses all of this information as context when processing subsequent client requests. If a client submits a query to retrieve account-specific information, the stateful service determines the ID and connected/disconnected state of the client. This state data affects how the app processes the request.
Stateful applications offer unique advantages in certain scenarios, providing power and efficiency for specific use cases. While stateless apps have their place, it’s crucial to recognize the benefits of stateful applications in modern web development.
A stateless application doesn’t save any client session (state) data on the server where the application lives. Instead, it stores all data on the back-end database or externalizes state data into the caches of clients that interact with it. In web applications, stateless apps can behave like stateful ones.
By using a Representational State Transfer (REST) API, developers can augment HTTP to make stateless apps to produce stateful behavior.
An example of this would be your username appearing in a website navbar following a successful login. This stateful behavior is possible because of a session identifier (typically a cookie) that the client saves on its own system.
While stateless apps can slow down certain types of client interactions, they offer virtually infinite scalability. In this respect, building stateless apps with REST APIs (instead of requiring the server to repaint what is presented to the browser window with each request) allows developers to achieve incredible scaling advantages while mimicking stateful operation.
So far, everything sounds excellent with stateful web apps. With their use of remote sessions, they offer historical context and speedy and efficient client interactions, but we haven’t gotten to the challenging parts. Stateful apps have some drawbacks – most importantly, scaling challenges.
Coming back to Fielding’s dissertation: “The advantages of the remote session style are that it is easier to centrally maintain the interface at the server, reducing concerns about inconsistencies in deployed clients when functionality is extended and improves efficiency if the interactions make use of extended session context on the server. The disadvantages are that it reduces scalability of the server, due to the stored application state, and reduces visibility of interactions, since a monitor would have to know the complete state of the server.”
Remember the local bank in the above analogy? Imagine 1,000 people line up to make transactions at the same branch location — and there’s only one branch location in town. There will be a long wait because the bank won’t be able to manage this many requests at once. You can’t simply go to a new bank, because they won’t know who you are, and they won’t have access to your account records at the other bank. The fact that you must keep going to the same bank branch — even when it’s being flooded with clients and can’t process your transactions — is a scaling problem. The bank in your town can’t scale to handle more than a certain number of transactions at once.
This scaling problem is similar in stateful apps. The users of stateful apps need to continue sending requests to the same system that maintains their state data – or they lose historical context. That means you cannot scale by redirecting new client requests to other systems running the same application. Clients will need to reauthenticate, and they will lose the historical context of previous transactions. When you need to provide the same app experience to a rapidly growing user-base – or to an unpredictable amount of client traffic – stateful apps can experience delays and shutdowns as traffic rises to levels that the server can’t handle.
The most popular way to prevent these scaling challenges is to use a stateless app. A stateless app interacts with more “sophisticated” clients that save their own state data. This allows a stateless app to achieve what looks like stateful operation – and it’s free to replicate itself for easier scaling.
A stateless application or stateless process doesn’t store any data related to past transactions on its server. It accepts each transaction or user interaction like a blank slate without knowledge of previous interactions. Similar to a Coke machine, the stateless app receives a single short-term request and delivers a single response.
In most cases, statelessness doesn’t mean that there isn’t a state. It just means that the state is held somewhere else. For example, when you use a Coke machine, you’re the one who maintains the state. After buying a drink, the machine doesn’t remember what kind of drink you purchased, but you do because you’re holding it in your hand. In this respect, it’s more accurate to say that a stateless application externalizes its state rather than maintaining it on the server. This is why many of the apps (clients) on your phone or computer have a cache. The cache saves state data on your local system to provide context for subsequent transactions.
Leonard Richardson and Sam Ruby described stateless systems best when they wrote, “Statelessness means that every HTTP request happens in complete isolation. When the client makes an HTTP request, it includes all information necessary for the server to fulfill that request. The server never relies on information from previous requests. If that information was important, the client would have sent it again in this request.”
As for the REST APIs used in scalable web applications, Fielding describes a “stateless constraint” that says: “Each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. Session state is therefore kept entirely on the client.”
Ultimately, a stateless application acts like a nameless agent or tool that clients use to interact with the databases (and possibly other services) it connects with. Since the application is stateless, a load balancer can infinitely replicate new instances of it – and balance client requests across those instances. This allows the system to scale and manage any level of traffic.
An excellent example of a stateless system is the DreamFactory API gateway. Similar to the security guard, DreamFactory waits for a client to submit an API request. The request contains all of the necessary authentication/password data and commands for DreamFactory to carry out. DreamFactory doesn’t know anything about the client but it uses its connected services to authenticate and carry out the request. As a stateless system, load balancing tools can scale DreamFactory across many different server instances to process virtually any number of requests.
Because of their unlimited scaling ability, stateless applications are essential to modern cloud computing and the internet. When you read the contents of a website, your web browser is a client that is using the stateless HTTP protocol to connect with a stateless web service. Each request your browser sends can work in isolation without the website knowing what the client did before. When request traffic increases, a load balancer can replicate a stateless web service on new servers and redirect client requests to maintain a seamless experience for new and returning users.
REST APIs adhere to the stateless principals behind the HTTP protocol, and they are the most common way for clients and users to interact with stateless applications. Each request to a REST API contains all of the information – such as authentication data, GET/PUT/PATCH/DELETE commands, etc. – that the stateless application requires to successfully handle a request. The application either returns the requested information (for example in a GET request) or indicates that the transaction was successful (for example in a PUT request). There are other types of APIs, but in most cases, REST APIs enable stateless transactions to occur.
Facebook Messenger is an example of a stateless application that uses a REST API. When you open the Messenger client on your smartphone, it sends a GET request through the Messenger REST API to retrieve your latest messages. On Facebook’s side, the app is stateless. It doesn’t require any knowledge of previous transactions to send your smartphone a response. It’s the client on your phone that stores historical data in its cache to provide historical context on your end. Again, if the Facebook Messenger Service overloads with client requests, a load balancer can manage the traffic by distributing requests to duplicate instances.
While stateful and stateless applications have fundamental differences, there are a few key similarities worth noting. Understanding these similarities can provide a broader perspective on the overall application architecture. Let’s explore the key similarities between stateful and stateless systems:
Stateful and stateless applications differ significantly in their approach to handling client data and processing requests. Understanding these key differences is crucial for making informed architectural decisions. Let’s explore the primary distinctions between stateful and stateless systems:
Before we finish this piece, it’s important to put stateless apps into the modern context of microservices and the microservices-based application architecture. Although microservices can be stateful, they are usually simple, stateless applications that focus on performing a single service. Stateless Microservices expose REST APIs that allow other apps and clients to interact with them.
Containerizing microservices lets you run them multiple microservices in isolation on the same server kernel as other microservices (this saves resources and server licensing fees). A containerized microservice has all of the code, libraries, and anything else it needs to run independently – but nothing more – wrapped into a single package. As Bizety notes: “Compared to a computer running on an ordinary operating system, programs running inside a container are only able to see the container’s contents and devices assigned to that specific container.”
Ultimately, developers can loosely connect a network of microservices to form a modular or “pluggable” microservices-based application architecture. Here’s how Martin Fowler describes this: “The microservice architectural style  is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery.”
“Fully-automated deployment machinery” in this case refers to technology like Kubernetes. Kubernetes is a container orchestration tool that performs automatic load balancing and other services to manage a microservices-based architecture. Essentially, it can automatically duplicate containerized microservices, distribute client traffic, balance server resources for optimum performance. All of this allows you to scale an application to deal with varying levels of client traffic. Kubernetes can spin-up thousands of containerized microservices to manage virtually any number of requests.
The decision to use stateful versus stateless apps boils down to your scalability requirements and what you need the app to do. If your app needs to store session data to process transactions in-context and if the server can handle the expected processing load, a stateful system is probably best. On the other hand, if you are building an app that needs to process REST API transactions, provide information in response to client requests – and traffic levels can grow exponentially – a stateless app is what you’ll be working with.
Most stateful and stateless applications offer REST APIs to make their services available to clients and users. Therefore, REST API development often goes hand-in-hand with application development – especially when building a scalable, service-oriented application architecture comprised of pluggable, stateless microservices. However, hand-coding a single REST API can add weeks or more to an app development timeline.
This is where the DreamFactory API gateway can help. DreamFactory itself is a scalable and stateless application that offers cutting-edge tools for building applications and managing API requests and interactions between them. One of DreamFactory’s most popular features is its automatic REST API generation tool that allows you to generate fully-documented REST APIs for any database in minutes.
Want to try DreamFactory for yourself? Sign up for a free hosted trial now!
Stateful apps save client session data on the server, providing historical context and faster processing. In contrast, stateless apps don’t save client session data on the server and rely on externalized state data.
Stateful apps use saved client session data to process new transactions. They store data from previous interactions on the server or in the caching tier, allowing for contextual processing.
Stateful apps offer improved speed and performance, historical context for users, reduced database queries, and enhanced scalability for predictable workloads.
Stateful apps face difficulties in scaling as users need to continue sending requests to the same system to maintain their state data. Scaling becomes a challenge when the server cannot handle increased client traffic, resulting in delays or system unavailability.
Stateless apps do not store data related to past transactions on the server. Each transaction or user interaction is treated as a fresh request without knowledge of previous interactions. The state is held elsewhere, such as in the client’s cache.
Stateless applications are generally more scalable as they do not bind clients to a specific server and can be replicated easily. They are suitable for handling increasing client traffic and achieving high scalability.
Fascinated by emerging technologies, Jeremy Hillpot uses his backgrounds in legal writing and technology to provide a unique perspective on a vast array of topics including enterprise technology, SQL, data science, SaaS applications, investment fraud, and the law. Contact Jeremy at [email protected].
Join the DreamFactory newsletter list.