Stateful Services
A stateful protocol retains previous session information as part of a user's state. This client session data (state data) allows the application to process subsequent transactions in the context of preceding ones. Using a database to store data doesn't necessarily mean an application is stateful- the important distinction is that the client's current state data is stored on the server itself.
Stateful Example
Online banking uses state to record a user's funds, linked accounts, and authorization. When a user deposits money into an account, the account's state changes and is saved on the bank's server. The user's name and password are stored on the bank's web server to be confirmed when the user logs in via their web browser. If the user changes their password, the password's state changes in the server.
Stateless Services
A stateless architecture retains no information as part of a user's state. Every interaction is independent of the server's state and depends only on the data held by the system (or in the request) at that moment. This means that every client request must contain all necessary information for the server to execute and respond to the request, including authentication keys. Where stateful protocol remembers the past, stateless protocol treats every action as if it is happening for the first time.
Stateless Example
REST is designed to be functionally stateless. Data required to complete the request is stored in key/value pairs within the request itself, travels via API to the server with the provided authentication, and the server performs the specified task, with the data contained in the request. The server returns a value and HTTP status code to the client. The next request starts the process over again, including authentication.
An example of a stateless API is the Phone Validation API. We can send this API a request for a phone number:
`curl 'https://phonevalidation.abstractapi.com/v1/?api_key={YOUR API KEY}&phone=14152007986'`
The Phone Validation API then checks the number against a database, and returns our request.
While the phone number's validity or location might change, at no point in this request did we need historical client data from the server to execute our request. We just sent a GET request with proper authentication attached through the API, with the number we are looking for, and received our information from the server.
Stateful vs Stateless
Stateful and stateless protocols both have their use cases, and it is up to the software engineer to judiciously apply them, but one serious shortcoming of stateful applications is they don't scale as well as stateless applications. Remembering one client session may not seem like much, but imagine millions of client sessions, with all their possible authentications, states, and changes, all requiring server-side storage and bandwidth. That is a significant overhead! A stateless protocol doesn't mean there is no state present, just that it is not stored on the server. Historical client data can be stored on the client side with cookies, or a GET request can retrieve client information from a database, but this application is still stateless because a client state is not stored on the server. This allows scalability and agility that stateful protocols do not, and brings us to containerization, microservices, and cloud computing.
State in the Age of Microservices
A container is an application with its runtime requirements included in the package. It is like a virtual machine, but much more lightweight, while still containing all dependencies and libraries necessary for the application's use. Containers have fundamentally changed what an application is. Microservices are an application, but broken into many pieces across different servers in the cloud. It is an application as a sum of its connections, instead of one application existing on one machine, with devops engineering orchestration of these applications. This is called "microservices architecture," vs the old way of "monolithic architecture."
Containers were initially stateless to encourage flexibility and portability, but containerized stateful applications and even containerized databases are now available. This gives users the flexibility and speed of using containers, but with the persistent storage and context of statefulness. Containerization also, however, blurs the line between stateful apps and stateless apps, and makes container implementation more complex, necessitating automation and container management solutions like Kubernetes.
Conclusion
No matter how complex your microservices architecture becomes, if the client state is stored on the server, it is stateful, and won't scale nearly as well as a stateless application. If your client state is stored in a cookie (or cache) on the client side, it is technically stateless. This cache might contain some basic client data, which the server will use to establish historical client information, but every request will contain all necessary information to execute the request on the server.
We hope this article has helped you understand the difference between stateful and stateless applications, and sets you on the path towards skilled implementation of containerization and microservices.