117

This may be a convoluted question, but I'm trying to get a better understanding of statelessness.

Based on what I've read, web applications should be stateless, meaning each request is treated as an independent transaction. As a result, Session and Cookies should be avoided (as both of them are stateful). A better approach is to use Tokens, which are stateless because nothing is stored on the server.

So I'm trying to understand, how can web applications be stateless when there is data that is being kept for my session (such as items in a shopping cart)? Are these actually being stored in a database somewhere and then periodically being purged? How does this work when you are using a token instead of cookies?

And then as a related question, are the major websites (Amazon, Google, Facebook, Twitter, etc.) actually stateless? Do they use tokens or cookies (or both)?

8 Answers8

106

"web applications should be stateless" should be understood as "web applications should be stateless unless there is a very good reason to have state". A "shopping cart" is a stateful feature by design, and denying that is quite counter-productive. The whole point of the shopping cart pattern is to preserve the state of the application between requests.

An alternative which I could imagine as a stateless website which implements a shopping cart would be a single-page-application which keeps the shopping cart completely client-sided, retrieves product information with AJAX calls and then sends it to the server all at once when the user does a checkout. But I doubt I have ever seen someone actually do that, because it doesn't allow the user to use multiple browser tabs and doesn't preserve state when they accidentally close the tab. Sure, there are workarounds like using localstorage, but then you do have state again, just on the client instead of on the server.

Whenever you have a web application which requires to persist data between pageviews, you usually do that by introducing sessions. The session a request belongs to can be identified by either a cookie or by a URL parameter you add to every link. Cookies should be preferred because they keep your URLs more handy and prevent your user from accidentally sharing an URL with their session-id in it. But having URL tokens as a fallback is also vital for users which deactivate cookies. Most web development frameworks have a session handling system which can do this out-of-the-box.

On the server-side, session information is usually stored in a database. Server-side in-memory caching is optional. It can greatly improve response time, but won't allow you to transfer sessions between different servers. So you will need a persistent database as a fallback.

are the major websites (Amazon, Google, Facebook, Twitter, etc.) actually stateless? Do they use tokens or cookies (or both)?

Do they allow you to log in? When you then close the tab and revisit the site, are you still logged in? If you are, then they are using cookies to preserve your identity between sessions.

Philipp
  • 23,488
69

It's true that web applications should be stateless. However, session variables, cookies, and tokens don't violate this when they are all stored on the client (web browser). They can be parameters in the request.

Here's a simplified model:

Web Browser (has state) <-> Web Server (stateless) <-> Database (has state)

This could work for Software Engineering Stack Exchange. This answer I'm typing is part of my web browser's state. So long as that's the only place where it is, it's not accessible to anyone but me. But as soon as I hit Post your Answer my browser sends it to the web server. The web server processes the post using no state of its own. It learns who I am from my browser and from the database. Once it's done checking my post, and adding it to the database, the web server promptly forgets about me.

That's what stateless means. The server is not responsible for remembering any of this. That's not its job.

Doing this has many advantages. If the web server has a memory leak it's detectable since its memory footprint shouldn't be growing. If the web server crashes, my identity doesn't go with it. If someone tries to do a denial of service attack, they can't use web server state resources to do it, because the web server doesn't allocate any state for them between sessions. This is all aimed at making the web server stable. That way, when it starts running, it stays running.

Now sure, I'm consuming resources in the database, but those resources have first been checked against my allowance by something stable that we can count on to protect the database from the wild and woolly web: the stateless, business rule enforcing web server.

candied_orange
  • 119,268
34

web applications should be stateless

Nonsense. Web requests should be stateless. Or more accurately, web requests are stateless.

But, saying that a whole application should be stateless is complete nonsense.

each request is treated as an independent transaction.

Yes, exactly. Or more accurately, yes, necessarily. Over HTTP, each request is inherently independent of all other requests. Adding "statefulness" to HTTP requires that you explicitly identify, store, and retrieve "state" for each "stateful" request. And that takes effort, decreases performance, and adds complexity.

And, for those reasons, each request that can be stateless "should" be stateless.

As a result, Session and Cookies should be avoided (as both of them are stateful). A better approach is to use Tokens

A few things: Tokens can be tied to session storage too. Cookies don't need to be tied to session storage. Tokens are often stored in cookies. And, sometimes a session is simply the right tool for the job.

That means that at least sometimes, sessions and cookies are just as "better" as tokens!

[Tokens] are stateless because nothing is stored on the server.

Well, that's it. That's what the "statelessness" dogma is really about. Though, to be clear, it's not about storing "nothing" on the server, it's about not storing session state on the server.

My Gmail inbox is in a state, for example. And it damn well better be stored on the server! But, it's not session state.

So, instead of having a servers that can take a small identifier and figure out who you are and so forth, stateless applications want to be reminded who you are and what you're doing with every bloody request. The application state still exists, the client is just responsible for holding onto it.

Now, if that state is small, that's probably OK. In some cases it's very good.

And then, of course, there are things we simply expect to be stateful ...

how can web applications be stateless when there is data that is being kept for my session (such as items in a shopping cart)? Are these actually being stored in a database somewhere and then periodically being purged?

Two options. Either you have a session, or you're in denial!

... But seriously. You wouldn't normally store a cart in a cookie. Something like a shopping cart will either be stored in a "traditional" session, or it'll be stored as a Cart object, with some kind of ID that the server uses to pull it into subsequent requests. Kind of like a .. uhh ... ... err ... session.

For real seriously: There's a large degree to which "statefulness" is just what we call it when two communicating agents can contextualize messages in a conversation. And a session, traditionally understood, is just what we typically call the mechanism by which this occurs.

I'd argue that, regardless of whether you use tokens or "sessions," for each request your server handles, you either need to contextualize that request to fulfill it, or you don't. If the context isn't necessary, don't fetch it. If the context is necessary, you better have it nearby!

And then as a related question, are the major websites (Amazon, Google, Facebook, Twitter, etc.) actually stateless? Do they use tokens or cookies (or both)?

Probably both. But, generally speaking, they do exactly what you do: They set cookies to identify "state" records in massive "session" databases.

When possible, I suspect they shove basic identity claims into short-lived "tokens" to avoid unnecessary contention on centralized storage. But, the fact that many of these services permit me to "log out of all other locations" is a good indicator that, if they're using tokens at all, they're at least "supported" by a semi-traditional session model.

svidgen
  • 15,252
16

Statefulness is not necessarily a bad thing, but you need to understand the difference between stateful and stateless apps. In short, stateful apps maintain information about the current session, and stateless apps do not. Information stored permanently as part of a user account may or may not be stored in a session, but storing information related to a user account does not by itself make the application stateful. Statefulness requires that the server maintain information about the current user's session beyond what the client browser is maintaining. For instance, a client could authenticate and be given a JSESSIONID cookie, which it then sends to the server with each request. If the server starts storing stuff in the application's session scope based on this JSESSIONID, it becomes stateful.

Statelessness

By stateless, we mean that the server and client are not maintaining current information about the user session. The client and server may use some form of token to provide for authentication between requests, but no other current information is stored. A typical use case for such a solution might be a news site where most users (new consumers) consume information but do not produce information that goes back to the site. In such cases, the site doesn't need to maintain any information about the current user session. Note that the site may still use cookies to identify the user and store information about that user's use of the site, but that may still be regarded as stateless since everything recorded could be transactional, e.g. what link the user clicked, which might be recorded by the server, but not maintained in a user session.

Statefulness on the server

On the server, a stateful app saves state information about current users. This approach generally involves using cookies to identify the user's system so that state can be maintained on the server between requests. Sessions may or may not be authenticated, depending on the context of the application. Stateful server apps offer the advantage of caching user state information on the server, speeding up lookups and page response time. On the down side, storing information in session scope is expensive, and at scale it becomes very resource intensive. It also creates a potential attack vector for hackers to try and hijack session identifiers and steal user sessions. Stateful server apps also have the challenge of protecting user sessions against unexpected service interruptions, e.g. a server failure. A common solution to this problem is to cluster sessions across a cluster of server machines, but again, at scale it quickly becomes impractical to cluster all sessions across all machines.

Statefulness on the client

Using JavaScript and modern browser technologies like sessionStorage, application can now easily store state information about a user session on that user's device. Overall, the application may still be considered stateful, but the job of maintaining state has been moved to the client. This approach has a big advantage (for the maintainer of the Web app) over maintaining state on the server in that each user is, in effect, maintaining their own state, and there is no burden on the server infrastructure. At web scale, that kind of architectural choice has huge repercussions for hardware and electricity costs. It could literally cost millions of dollars a year to maintain state on the server. Moving to a system maintaining state on the client could then save millions of dollars a year.

Tokens v. cookies

Cookies act as identifiers for client devices/browsers. They can be used to store all manner of things, but generally they store some form of identifier, like CFID/CFTOKEN in CFML apps. Cookies can be set to live in the user's browser for a long time, making it possible to do things like maintain authentication on an app between browser sessions. Cookies can also be set to memory-only so they expire when a user closes the browser.

Tokens are generally some kind of identifying information about the user that are generated on the server ( using encryption to scramble the information ), passed to the client, and returned to the server with the subsequent request. They may be passed in the header of the request and response, which is a common pattern in single page applications. Ideally, each request/response results in the generation of a new token, so tokens can't be intercepted and used later by an attacker.

Single Page Apps and client state

With SPAs, state information is loaded into the client browser and maintained there. When the state changes, e.g. you post an update to your social media account, the client relays that new transaction to the server. In this case, the server saves that update to a persistent data store like a database, and relays whatever information back to the client that it needs to synchronize with the server based on the update (e.g. an ID for the update ).

Note that this pattern of storing state on the client offers advantages for online/offline experiences in that you can be disconnected from the server while still having a somewhat usable application. Twitter is a good example of this case, where you can review anything loaded client side in your Twitter feed even if you are disconnected from the Twitter server app. This pattern also creates complexity in synchronization between server and client, which is a whole subject of its own. The complexities of the solution are a tradeoff for being able to maintain state on the client.

Statefulness on the client makes web apps feel and behave more like traditional desktop apps. Unlike desktop apps, you will typically not have all of your account information loaded into your client session in a browser. Doing so would in many cases be impractical and produce bad experiences. Can you imagine trying to load an entire Gmail box into the browser? Instead, the client maintains information like what label/folder you are looking at and where in the list of emails in that folder you are looking. Balancing what state information to maintain and what to request as needed is another engineering challenge of this pattern, and again, it represents a tradeoff between practicality and providing good user experiences.

Shopping carts and the like

As for specifics like shopping carts, it really depends on the solution. A shopping cart may be stored in a database on the server, it may be stored only in session scope on the server, or it may even be stored in the client. Amazon has persistent shopping carts for logged in users, and "temporary" carts for anonymous users, though these carts are persistent to some extent.

When you talk about something like Google, which is really a bunch of different applications living under the same brand, they probably do not share a common architecture, and each is built in the way that best meets the needs of its users. If you want to learn how a site is built, open the developer tools in your browser and look at it. Check for cookies, watch network traffic, and see how it runs.

Sorry if this answer rambles a bit, but statefulness is a complex subject.

Robert Munn
  • 1,309
6

The protocol is stateless.

But from that it doesn’t necessarily follow that applications using the protocol should be stateless.

Here are a couple of related StackOverflow answers that explain the difference well:

6

Sessions and cookies don't have to be avoided. You can still have them with stateless web applications.

There is a big difference between Java and Ruby on Rails. Java apps will store the session in memory using a session key stored in a cookie. This is fast to retrieve the user state and shopping cart. However, you have to always hit the same server with your session.

Rails apps store the user id in a signed, encrypted cookie. It can't be tampered with. When you load a page, the web app fetches your state, user, and shopping cart from a database. This is slower, but the key is, you can hit any instance! This allows you to restart, scale, shutdown instances at will. Very convenient. It can also be made faster with a shared, in-memory, cache database like Redis. Or you can store the shopping cart in the cookie, provided it's small enough.

So you can achieve statelessness, through clever techniques, and add the ability to scale at will.

Chloe
  • 448
5

When referring to stateless - e.g. in a RESTful HTTP Service - it's about to avoid storing state on the server side. At best, that includes also avoid storing any state in a database or other persistent storages on the backend. To make it clear I am talking about a state not data in general. It seems that some guys are mixing things up.

A stateless communication has several benefits especially regarding scalability and availability.

A better approach is to use Tokens, which are stateless because nothing is stored on the server.

That's true (for certain authentication and authorization protocols). Tokens can (but not per se) provide all information within the request which is needed to authenticate an user or authorize an action. For an example take a look at JWT.

So I'm trying to understand, how can web applications be stateless when there is data that is being kept for my session (such as items in a shopping cart)? Are these actually being stored in a database somewhere and then periodically being purged? How does this work when you are using a token instead of cookies?

Regarding the shopping cart example. It's no problem to store all the cart items on client side without using a session or cookies. You can find an example on smashingmagazine.com. But it's also possible to realize a stateless shopping cart with cookies (at least if your assortment is not so big and 4kb storage is enough for you).

Don't get me wrong, that doesn't mean you should implement a shopping cart stateless to any price. Amazon or other big online shopping platforms are using stateful shopping cart implementations because user experience and usability is more important for them than fitting technical non-functional requirements like scalability.

Generally, tokens are not used to store information like cart items. They are used for a stateless authentication and authorization.

And then as a related question, are the major websites (Amazon, Google, Facebook, Twitter, etc.) actually stateless? Do they use tokens or cookies (or both)?

If you are asking if they are using cookies or tokens for authentication, the the answer is they use both. For users mostly cookies for technical clients mostly tokens are used.

0

OK, the rule you quote is technically incorrect. All the layers of a web application have state.

The intent of the rule is "don't hold per-session state server side".

I.e., session variables in ASP, which were commonly used to do things like items in basket/user name, etc.

The reason is that you will run out of memory on the server as your application gains more users. Moving the storage to a database or shared cache doesn't solve the problem as you still have a bottleneck.

To maintain per-user application state without hitting this problem, move the state to the client side. For example, put the basket items in a cookie or more advanced client-side storage.

Because the number of clients scales with the number of users, your application as a whole won't have a bottleneck and will scale well.

Ewan
  • 83,178