Let's say we have developed an application. For the sake of simplicity, let's assume that we have only two pages, login page and user profile page.
We should display the profile of the user only when they are logged in. Let's see how stateful application and stateless application handles this.
Stateful:
If we choose to use stateful architecture, we will have to store the state of the user(s) somehow. Usually the state is stored in the server itself.
But what if the server goes down? Since we store the state in the memory of the server, we could possibly lose all the stored states. It's hard to restore the state.
On the upside, we don't have to query the database everytime we receive a request, to check if the user is logged in or not.
What if we decide to have more than one server?, Let's say the user logs in by sending a request to server-1 and the state is stored in server-1. Now the user is trying to access their profile page, due to high traffic the request is directed to server-2. Remember, the state is stored in the memory of server-1 only, so according to server-2, the user is not logged in. This might lead to inconsistency. Hence, stateful application might not go well with horizontal scaling.
Advantages:
No need to query the database.
It is quick, as we don't have to query the database everytime.
Disadvantages:
If the server goes down, it will be hard to recover.
We can't scale up horizontally.
Stateless:
In case of a stateless architecture, a token is sent back to the client, when the user logs in. This token is stored in client's storage. Then this token is sent along with every request the user makes.
Inorder to make sure that the request is coming from an authenticated user, we check the token sent along with the request, against the data we stored in the database.
Since the token is stored in client's storage, we can easily recover if the server goes down. And horizontal scaling is much easier in stateless architecture.
But the catch here is, we have to query the database everytime we get a request.
Advantages:
Horizontal scaling is easy.
We can easily recover if our sever goes down.
Disadvantages:
We have to query our database, for every request.
Slower than stateful architecture.
I hope this article helped you. Want to connect with me? my DM is open on dev.to, you can connect with me on twitter
Top comments (5)
I'm a big fan of stateful actor approach, where most of the time every node in the system is stateful, but writes asynchronously its state for the sake of recovery after crash or sth. This approach has been successful in Akka.Net and similar actor model libraries, see a wonderful article about it by Petabridge petabridge.com/blog/stateful-web-a....
Thanks for sharing!, I will check it out.
Ultimately depending on the type of service, you will probably end up with a mix, where some of the data is always pulled from the database and some of it is retained.
Example:
User Presence is not reliable when only relying on the database, when a server goes down in a not-so-graceful way, you cannot rely on the database being up to date. For volatile data like this, you either set TTLs on DB records and then you have a delay between when all the users are reported as offline, or you retain the presence in memory realtime so you can report accurately at a given moment.
For data that is reliable when only relying on the DB, it should be done that way, so you can depend on an ACID compliant solution for state, rather than hoping the memory isn't inaccurate. Traffic on the DB is much more efficient than you think, and you can scale your DB in most cases you might not have the ability to scale the app when the state becomes unmanageable.
Think of it as RAM vs ROM, RAM is volatile, so if you need stability and accuracy of data, RAM is not the right way to go about it in most cases.
It's good to know the stateful vs stateless is also relevant for microservices: devopedia.org/microservices