Create your own
Lesson illustration

Stateless vs. Stateful Web Interactions

Hello again. In the previous lesson, we separated persistent application data from stateful request handling. A database can hold durable orders while web-server instances remain stateless; conversely, a server can hold temporary session data in its own memory and therefore handle requests statefully.

This lesson makes that distinction operational. You will learn to inspect a web interaction and classify it by asking one precise question: what, if anything, must the server recover from an earlier interaction to handle the current request correctly? This will also prepare us to examine session identifiers and cookies in the next module.


The classification is about dependence on prior requests

A request is stateless when the server can handle it using the information in the current request, plus ordinary shared resource data such as a product database. The server does not need a record of the client’s earlier conversation.

A request is stateful when its correct handling depends on client-specific context established earlier, and the server must recover that context from somewhere outside the current request. That context might include:

  • whether this browser has an active login session;
  • the current step in a multi-page form;
  • an unfinished checkout;
  • a user’s temporary preferences or selections;
  • work in progress, such as an editing lock or draft.

The important word is context. A server may query a database during a stateless request; querying data alone does not make the interaction stateful. The question is whether that query restores a remembered conversation with this particular client.

Stateful interaction: “To understand this request, I must recover what this client was doing before.”
Stateless interaction: “This request tells me what operation to perform and what resource it concerns.”

There is one useful complication: always state the scope of your classification.

  • At the interaction level, a server-side session is stateful even if its data sits in a shared store.
  • At the web-server-instance level, a service can be stateless if any instance can retrieve necessary data from shared storage rather than relying on its own memory.

Those statements are compatible. The application maintains user context, but no particular web server owns it.

The left side depicts an application coupled to its own user and session data, so a particular application instance carries important context. The right side depicts multiple application instances separated from shared state and data stores, allowing the instances themselves to remain stateless.

Resource state is not session state

A useful distinction from REST terminology is between resource state and application state:

  • Resource state is the current data of something the system manages: a product, order, account, document, or cart record.
  • Application state is context about a particular client’s ongoing interaction: which user is currently authenticated, which checkout step they reached, or which temporary options they selected.

Read the following short explanation before applying the distinction to examples.

Stateless REST API: Advantages of Statelessness in REST

Read this RESTfulAPI.net article to sharpen the distinction between a server storing resources and a server maintaining a client session. Its terminology gives us a compact way to avoid calling every database-backed application “stateful.”

In Section 1, “What is a Stateless REST API?”, read the opening definition. Then continue into Section 2, “Application State vs Resource State,” and read the comparison. Focus on the difference between data about a resource and data used to recognize or continue a particular client interaction.

Consider these two requests:

GET /products/482
GET /orders/ORD-9381
Authorization: Bearer <credential>

The server may look up product 482 or order ORD-9381 in a database. That does not mean it remembers earlier requests. The current request identifies the target resource, and the database is the authoritative source of that resource’s current state.

Now contrast that with:

POST /checkout/next
Cookie: session_id=K7x...

Suppose the request body does not identify a checkout or provide the current step. Instead, the server uses session_id to retrieve:

session K7x...:
  user: Priya
  cart: cart-73
  checkout step: shipping address
  delivery option: express

The server must recover client-specific context created earlier. At the interaction level, this is stateful.

The cookie value does not itself contain the meaningful context in this example. It is an opaque handle that lets the server find the context it remembers.


A session cookie: a compact example of stateful interaction

The following diagram shows the usual pattern. The browser signs in, receives a session-ID cookie, and sends that cookie with a later request. The server then determines its response from the session’s validity and data.

A browser sends a sign-in request, receives a session-ID cookie from the server, then includes that cookie in a later page request; the server uses the identifier to associate the request with stored session context.

This does not change the nature of HTTP itself: HTTP still does not inherently link one request to the next. Rather, the application adds a linking mechanism:

  1. The browser receives and stores an identifier.
  2. A later request carries that identifier back to the server.
  3. The server uses it to recover the relevant client-specific context.
  4. The server can now provide a continuous user experience.

A cookie is therefore neither automatically good nor automatically stateful. It is simply a browser-managed value sent under rules chosen by the server. If it contains an opaque session ID that requires a server-side lookup, it commonly supports a stateful session. If it holds a self-contained value that the server can validate without retrieving session context, request handling may be stateless with respect to the session. We will compare these designs later in the course.

For a brief verbal explanation of this contrast, watch the opening of this video.

Stateful vs Stateless: Which One Do YOU Need?

In “Stateful vs Stateless: Which One Do YOU Need?” from The Coding Gopher, the opening definition frames the exact test used in this lesson: whether the backend consults saved context or whether every request stands independently.

Watch the core contrast. Listen for the two sides of the classification: a stateful backend consults saved session information, while a stateless backend receives all required execution context with the current call.


A reliable classification method

When a design is not obvious, use the following method. It is deliberately more precise than asking whether the system “has state,” because virtually all useful applications do.

1. Identify the unit being classified

Say what you mean:

  • The interaction or API session may be stateful.
  • An individual application instance may be stateless because it uses a shared session store.
  • The overall system certainly has state if it stores users, orders, documents, or sessions.

For this lesson, start by classifying the interaction. Then, if architecture matters, separately classify the web-server tier.

2. List what the current request actually provides

Include everything sent with the request:

  • URL path and query parameters;
  • request body;
  • headers such as an authorization credential;
  • cookies;
  • a client-held token;
  • an explicit resource identifier.

Do not assume that “the browser knows” a value unless the browser actually sends it.

For example, a request with page=4&sort=newest provides its own display context. A server need not remember that the client previously viewed page 3.

3. Identify the server-side lookup and its purpose

A database lookup can play two very different roles.

Lookup purposeExampleDoes it imply a stateful interaction?
Retrieve the requested resourceFetch order ORD-9381No, not by itself
Recover a client’s prior contextFind the checkout step mapped to session K7x...Yes
Validate a self-contained credential against a current user recordLoad a user’s current permissionsUsually no session state is required
Recover a server-created workflow recordFind a saved application draft and its next permitted actionOften yes, if it continues a client-specific workflow

The decisive question is not “Did the server look something up?” It is:

Is the server restoring interaction context that the current request did not otherwise provide?

4. Apply the fresh-server test

Imagine that the server process which handled the previous request disappears. A newly started server receives the next request.

  • If it can process the request correctly from the request itself and shared resource data, the server instance is stateless.
  • If it needs private memory from the old instance, that server-instance design is stateful.
  • If it fetches a client session from shared storage, the instance is stateless, but the interaction still uses server-side state.

This test prevents a common mistake: calling a service stateless merely because it has several servers, or calling it stateful merely because it has a database.


Worked classifications

Reading a product page

GET /products/482

The request identifies the product. Any server can query the product catalogue and return the current representation. The catalogue is persistent application data, but the interaction is stateless.

Even if the user viewed product 481 just before this request, the server does not need to know that history to show product 482.

Continuing a server-managed checkout

POST /checkout/next
Cookie: session_id=K7x...

The server looks up the session and discovers that the user has already chosen shipping, has a cart, and is now allowed to enter payment details. The current request alone does not convey that workflow context.

This is a stateful interaction. If the session is stored only in one server’s memory, the particular server instance is stateful too. If the session is in a shared store, the web-server instances can be stateless while the checkout interaction remains stateful.

Querying a cart as a resource

GET /carts/cart-73
Authorization: Bearer <credential>

This can be designed as a stateless interaction. The request identifies the cart resource; the server authenticates the requester, verifies access, reads the cart, and responds. A cart may still be persistent, user-specific, and valuable. None of those facts automatically make request handling stateful.

Compare this with the checkout example: the difference is not that one system has a cart and the other does not. The difference is whether the server must recover unstated conversational context, such as “what stage has this browser reached?”

A search request with explicit filters

GET /search?q=headphones&brand=Acme&sort=price&page=2

Every value needed to execute the search is present. The system might cache results internally for performance, but it need not remember this client’s earlier requests. This is stateless.

A multi-step application form

Suppose a user first submits personal details, then employment details, then a final confirmation.

There are two possible designs:

DesignWhat happens between stepsClassification
Server-side draft sessionThe server stores incomplete answers and current step under a session IDStateful interaction
Client supplies a complete signed draft on every stepThe request carries the form state and step information; the server validates it without retrieving a sessionStateless request handling with client-held state

The user experience may look identical. The classification depends on where the necessary context is retained and whether the server must restore it from a previous interaction.


The database misconception, resolved

It is tempting to reason:

“The server remembers orders in a database, so every order API is stateful.”

That statement merges resource persistence with session state.

An order database contains business facts that should outlive an individual user session: what was purchased, the charged amount, fulfillment status, and payment outcome. A request to retrieve an order can be independent even though it reads these durable facts.

By contrast, a server-side session answers questions about a current interaction:

  • Which user is this request associated with?
  • Are they still signed in?
  • What were they doing a few minutes ago?
  • Which temporary choices have they made?
  • Which workflow transition is valid now?

An application can use both forms of state at once. For example, it can process a stateless GET /orders/ORD-9381 request while separately using a stateful session to give a browser a personalized checkout experience.


A practical habit for reviewing real systems

When examining an endpoint, browser network trace, or design proposal, write two short statements:

  1. Current-request facts: “This request explicitly provides …”
  2. Recovered prior context: “The server must look up … because …”

If the second statement names client-specific history or a server-side session, the interaction is stateful. If it names only a resource identified by the request, it may be stateless.

Then add one architecture statement if needed:

“Any application instance can handle this request because the required information is available from shared storage.”

That sentence describes a stateless server tier. It does not erase the application’s session or business state.


Key takeaways

  • Classify an interaction by whether the server must recover client-specific context from earlier requests.
  • A database lookup is not automatically stateful. Retrieving a resource such as an order or product differs from restoring a user’s session or workflow.
  • A session-ID cookie commonly signals a stateful interaction because the server uses the ID to find stored session context.
  • A shared session store can make individual web-server instances stateless without making the user interaction sessionless.
  • Always name the scope: interaction state, web-server-instance state, and persistent application data are related but distinct concepts.

Next, we will focus on the session-ID pattern itself: how an identifier links separate HTTP requests to a server-side session, and what the server actually does when it receives that identifier.

Can't find a good explanation? Sign up and we'll make it for you

Sign up