by Jeremy H • September 28, 2020
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?
In this guide, we’ll provide in-depth answers to these questions – not only so you can better understand how stateful and stateless applications work – but also to put these ideas into the context of modern web development.
Sign up for our free 14 day hosted trial to learn how.
Please use these links to navigate the guide:
Let’s start with a brief overview of stateful and stateless applications:
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.
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.
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.
Another example of a stateful application is a stateful FTP server. Interacting with a stateful FTP server is similar to that of a stateful web service. The FTP server understands a user’s connection status, which means that authentication isn’t required with every request.
In conclusion, stateful apps save state data like authentication state, preferences, recent actions, and UI arrangement such as window location. That way, a client that gets interrupted can return to a saved state as if nothing happened. As long as the server can handle the client request load, stateful apps are fast because they don’t need to process as much data in each client request (in contrast to a stateless app that needs to receive and process authentication and other state data inside each request). Moreover, stateful apps don’t have to query their databases for as much information when processing requests.
Key takeaways: Stateful systems use databases like any application, but they also maintain “state data” (related to client authentication and past requests) on the server itself. This makes stateful apps fast and it allows clients to interact with the application within the historical context of previous interactions.
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.
Key takeaways: Stateful apps bind clients and users to the same server so it can process subsequent requests in the context of previous ones. Stateful systems work best under predictable workloads that the system can manage. If traffic grows, you can’t simply replicate a stateful app and redirect new client requests because users will need to start from scratch. This makes stateful apps difficult to scale and prone to system unavailability when client traffic increases.
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.
Image source: https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm
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.
Key takeaways: With stateless systems, the state does not disappear. It just gets externalized into the clients and/or databases that the stateless app interacts with. In this respect, stateless apps require more sophisticated clients that cache their own state information, which provides the context for subsequent transactions. Now, stateless apps and their clients interact with greater independence.
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.
Fielding Identifies three advantages of adhering to the REST constraint:  Visibility is improved because a monitoring system does not have to look beyond a single request datum in order to determine the full nature of the request.  Reliability is improved because it eases the task of recovering from partial failures.  Scalability is improved because not having to store state between requests allows the server component to quickly free resources, and further simplifies implementation because the server doesn’t have to manage resource usage across requests.”
Key takeaways: Stateless applications are vital to modern cloud computing and web services. Most stateless apps expose REST APIs so other clients and services can interact with them. Many of the most popular web sites, web services, social media platforms, and internet-based apps are stateless.
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.
Key takeaways: When containerized microservice are stateless, they support scalability and high availability because container orchestration and load balancing tools automatically spin up new instances of individual app components as client traffic requires. This achieves an agile framework that scales up or down to handle any level of traffic.
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!
Join the DreamFactory newsletter list.