88

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)?

  • 38
    I've seen and talked to developers lately who are obsessed with statelessness to the point of distraction. Its nice to have statelessness for re-usability but its not realistic to pursue that goal in every situation over every other goal unless you have a ton of resources to do that for some reason, like scaling. – Mark Rogers Apr 10 '17 at 2:49
  • 4
    @MarkRogers Why? Statelessness has nothing to do with reusablility. And being stateless doesn't leads to an higher effort. – Paul Wasilewski Apr 10 '17 at 10:40
  • 3
    @PaulWasilewski: And being stateless doesn't leads to an higher effort. => it does, with a stateful application you keep everything in memory tied to the session. This does not scale well, though works with session pinning, but it's VERY simple. When servers need to start exchanging information between each others, troubles start. – Matthieu M. Apr 10 '17 at 13:46
  • 6
    Looking at amazon, you'll notice that your cart remains even if you change computer, so it is not stored in cookie, but rather in a database. – njzk2 Apr 10 '17 at 13:55
  • 19
    If you don't get around to reading my answer. Here's the short version: Web requests are inherently stateless. Web applications are not. (No matter what some "stateless web" dogmatists tells you!) – svidgen Apr 10 '17 at 14:54
88

"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.

  • 44
    I think one of the confusions here is the distinction between a "web application" in the broad sense of the user's perspective, and "web application" in the narrow sense of "the code running on the web server". It's the latter that is often argued to be stateless not the former. As you say, it makes no sense for the former to be stateless in general as state is usually part of the business logic. For the latter to be stateless simply means that state needs to be stored on the client or the database server or both and not on the web server. – Derek Elkins Apr 10 '17 at 1:19
  • 16
    "[...] but then you do have state again, just on the client instead of on the server." It's about having no state on server side, to achieve better scalability and availability. If a state is stored on client side doesn't matter. – Paul Wasilewski Apr 10 '17 at 9:59
  • 5
    @njzk2 can you elaborate so that this doesn't sound absurd? Users don't go to Amazon to buy more names. And, after they make their purchase, something disappears which only existed while they were shopping. If that something is not "the state of the application", then what is it? If applications do not have state, what do they have? – user251748 Apr 10 '17 at 14:00
  • 3
    @nocomprende: I think njzk2's general gist is that the contents of your cart, like your full name, is data that a webapp persists on the server side. When people say, "webapps should be stateless", they usually mean something different from "webapps should not access a database containing your full name associated with your username". Precisely what they do mean by "stateless" perhaps is not trivially defined, since once you have that database there's all kinds of nonsense that you could persist in there, to support overly-complex app state, but shouldn't ;-) – Steve Jessop Apr 10 '17 at 14:12
  • 4
    @nocomprende: unscramble an egg by rolling back the database: since our webapp is stateless it can resume as before ;-) – Steve Jessop Apr 10 '17 at 14:20
53

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.

  • 8
    I don't know... This answer sounds a bit like saying: "Excel doesn't store your spreadsheet, the disk drive does!" Ha ha, isn't the database part of the web server, as far as most people are concerned? Obviously state is not stored in the CPU or code of the server, and keeping it all in memory is pretty silly. – user251748 Apr 10 '17 at 12:17
  • 6
    @nocomprende No, the database is usually not part of your web server. Yes, storing state in a database quite possibly limits scalability of the overall application, but there are relatively few applications that can offload all of their state (or even all the "per user" state) onto the client. Database servers are specifically designed to scalably handle state and, as CandiedOrange mentions, they're usually better protected, provisioned, and vetted than web servers. There are benefits to being easily able to scale web servers even though that doesn't solve all scalability problems. – Derek Elkins Apr 10 '17 at 12:32
  • 9
    @nocomprende: The point of saying that the database is not part of the webserver is that you can have a single database (or database cluster) for 1, 2, 3, .... webservers. This is how being stateless is meant to increase scalability: you can scale the database cluster and the number of webservers independently. – Matthieu M. Apr 10 '17 at 13:50
  • 4
    "It's true that web applications should be stateless." No. This is complete nonsense. – svidgen Apr 10 '17 at 14:47
  • 4
    This answer is the one I like the best because it best illustrates the usage of "stateless" in web dev. The server isn't maintaining state between requests. All state must come from the client (ie, part of the request) or from the database (likely based on the request). As an aside, there totally often is some state in the web application (eg, static instances of stuff), but in general, you'd want to design things to be stateless. This answer seems better than the accepted one for actually explaining the idea of statelessness best. – Kat Apr 11 '17 at 22:01
27

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.

  • 3
    Agree. It reminds me of the "immutable data" idea. If it is immutable, carve it in a rock, don't waste a computer to do that. Let computers do stuff with data! That is why we built them! Applications work with data. Data that is constant is useless. – user251748 Apr 10 '17 at 19:47
  • @nocomprende FYI, I will be making an addendum to this later. I feel like my answer's missing part of the OP's underlying question. Because, there is a legit concern floating behind the "stateless application" idea. But, the answer is along the lines of, when people say 'stateless', what they mean to say is 'relies minimally on server-side sessions.' – svidgen Apr 10 '17 at 19:53
  • 4
    @nocomprende: immutable data structures is something different, and is a tool used to manage lifecycles of memory objects. – whatsisname Apr 11 '17 at 2:07
  • 1
    Love your first line of explanation. When we discuss something, each verbal statement we make instantly dies away into oblivion. But somehow, we are still able to carry on a conversation, eh? It's Magic! – user251748 Apr 12 '17 at 14:48
  • 1
    @nocomprende This is an interesting discussion, but I guess we shouldn't continue it here. – pabrams Feb 23 '18 at 16:14
12

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.

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.

5

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:

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.

-2

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.

  • 2
    While memory leaks and denial of service issues were a factor, I think a more significant driver nowadays is elasticity and robustness to failure of a web server which is, of course, also related to scalability. The idea is if a server gets overloaded or even crashes, I can just reroute future requests (and with a bit more care even replay failed requests) to new web servers without coordination or losing state (as the user sees it). – Derek Elkins Apr 10 '17 at 7:46
  • hmm kind of. If you have per user info on the server, even if its distributed you still have a scalability problem. – Ewan Apr 10 '17 at 8:38
  • There's plenty you can do if pulling data from the disk is the bottleneck such as caching. – JeffO Apr 10 '17 at 21:07
  • no, there is an inherent problem if you hold that per session data. either you move it off the webserver to its own high availablity system or get rid of it all together by moving it to the client – Ewan Apr 11 '17 at 10:24
  • 1
    All this discussion about trying to avoid the hot potato really mystifies me. Whatever happened to the old saying, "The buck stops here"? Something has to manage the data, my bank would not like me keeping all of my financial transaction info only on my laptop. Why is everyone running away screaming from data? It is why we have computers! Crazy. – user251748 Apr 12 '17 at 14:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy