State Management

Remembering Users in a Stateless World

"HTTP is stateless by design — each request is completely independent. The server has no built-in memory of previous requests. Every login, shopping cart, and personalized experience exists because developers explicitly manage state."

CSE 135 — Full Overview | Review Questions

Section 1The Fundamental Problem

HTTP is stateless — the server forgets you between every single request.

Stateless HTTP: The Server Forgets

Browser Server │ │ │---- GET /page1.html ------------>│ Request 1 │<--- HTML response ----------------│ │ │ (server forgets everything) │---- GET /page2.html ------------>│ Request 2 │<--- HTML response ----------------│ │ │ (server forgets everything) │---- POST /login ---------------->│ Request 3 │<--- "Login successful" -----------│ │ │ (server forgets everything!) │---- GET /dashboard ------------->│ Request 4 │<--- "Please log in" -------------│ ← Who are you?
HTTP is stateless by design — each request is independent. This makes HTTP simple, scalable, and reliable. Any server can handle any request, making load balancing trivial. But it means we must explicitly manage state ourselves.

Section 2Where State Can Live

Client-side, server-side, or hybrid — three fundamental options, each with trade-offs.

Client-Side vs Server-Side State

Client-Side (in the browser)

  • URL Parameters?q=search&page=2
  • Hidden Form Fields — invisible inputs
  • Cookies — sent with every request
  • localStorage — persistent, ~5MB
  • sessionStorage — tab-scoped, clears on close
  • JWT — self-contained signed tokens

Server-Side (on the server)

  • Session Files — data on disk, keyed by session ID
  • Databases — MySQL, PostgreSQL, etc.
  • In-Memory Stores — Redis, Memcached
Server-side is more secure — data never leaves your control. Client-side is more scalable — no server memory per user.

The Hybrid Approach (Most Common)

Browser Server │ │ │---- POST /login ---------------->│ │ │ Create session: {id: "abc123", user: "alice"} │ │ Store in /tmp/sessions/abc123 │<--- Set-Cookie: SESSID=abc123 ----│ │ │ │---- GET /dashboard ------------->│ │ Cookie: SESSID=abc123 │ │ │ Look up session abc123 │ │ Found: user is "alice" │<--- "Welcome, Alice!" ------------│
The cookie holds only an ID. All actual user data stays on the server. This combines the convenience of automatic cookie sending with the security of server-side storage.

Section 3State Mechanisms Comparison

Seven mechanisms — each with different persistence, size limits, and security profiles.

Mechanism Comparison Table

MechanismLocationPersistenceSize LimitSecurity
URL ParametersURL (visible)Per-request only~2KBVisible in logs, history, Referer
Hidden FieldsHTML formForm submissionUnlimitedUser can modify via DevTools
CookiesBrowserConfigurable~4KB per cookieSent with every request; HttpOnly option
localStorageBrowserPermanent~5MBJS access only; same-origin policy
sessionStorageBrowserTab lifetime~5MBJS access only; per-tab isolation
Server SessionsServerConfigurableUnlimitedOnly session ID exposed to client
JWTClient (token)Token lifetime~8KB practicalSigned but not encrypted
Never put sensitive data in URLs — visible in server logs, browser history, and Referer headers. Use cookies or server sessions for anything private.

Section 4When to Use What

Choosing the right mechanism depends on what you're storing, who needs it, and how long it should live.

URL Parameters, Cookies & localStorage

URL Parameters

Shareable, bookmarkable state

  • Search queries: /search?q=web
  • Pagination: /products?page=3
  • Filters: ?category=books&sort=price

Cookies

Automatically sent to server

  • Session identifiers
  • Auth tokens
  • Language / theme prefs
  • Tracking identifiers

localStorage

Persistent client-side data the server doesn't need — cached API responses, offline data, UI preferences

Cookies are sent with every request. A 4KB cookie on a site with 50 resources per page = 200KB of extra upload bandwidth. Keep cookies small — use server sessions for large data.

sessionStorage & Server Sessions

sessionStorage

Temporary, tab-scoped state

  • Form drafts
  • Multi-step wizard progress
  • Temporary UI state
Tab duplication copies sessionStorage. But closing the tab destroys it permanently — there is no recovery.

Server Sessions

Secure user-specific data

  • Authentication state
  • Shopping carts
  • Any sensitive user data
Best security model: only a session ID crosses the network. All real data stays on the server.

Section 5Interactive Demos

Hands-on examples for each state mechanism.

Demo Links

  • URL Parameters — Pass data via query strings
  • Hidden Form Fields — Multi-step form wizard pattern
  • Cookies — Set, read, and delete cookies
  • Server Sessions — PHP session-based login flow
  • Client Storage — localStorage vs sessionStorage
  • JWT — Stateless token-based authentication
  • Security Patterns — CSRF protection, flash messages
See the full overview for live demo links. Each demo lets you inspect the mechanism in action using browser DevTools.

Section 6Security Considerations

Every state mechanism has attack vectors — know the risks and mitigations.

Risks & Mitigations

MechanismRisksMitigations
URL ParamsLogged in server logs, history, RefererNever put sensitive data in URLs
CookiesXSS can steal; CSRF can abuseHttpOnly, Secure, SameSite
localStorageAny JS can read (XSS)Never store tokens; sanitize inputs
SessionsSession fixation, hijackingRegenerate ID on login; use HTTPS
Hidden FieldsUser can modify via DevToolsNever trust for auth; validate server-side
JWTXSS if in localStorage; hard to revokeStore in httpOnly cookie; short expiry
XSS can read localStorage/sessionStorage — never store auth tokens there. Always set HttpOnly, Secure, and SameSite on session cookies.

Section 7Decision Guide

A quick decision tree for choosing the right state mechanism.

Quick Decision Tree

  • Sensitive auth data? → Server Sessions or JWT (in httpOnly cookie)
  • Should be bookmarkable/shareable? → URL Parameters
  • Part of a multi-step form? → Hidden Fields or Sessions
  • Needs to persist across sessions? → Cookies or localStorage
  • Tab-specific temporary data? → sessionStorage
  • Stateless API authentication? → JWT

Common Mistakes

  • Storing passwords or tokens in URL parameters — visible in logs and Referer headers
  • Storing JWT in localStorage for an SPA — any XSS steals the token
  • Using cookies for large data — sent with every request, bloating bandwidth
  • Trusting hidden form fields for authorization — trivially editable in DevTools
  • Storing sessions on disk in a multi-server setup — breaks when load balancer routes to a different server

SummaryKey Takeaways

7 sections of state management fundamentals in one table.

State Management at a Glance

ConceptKey Points
The Fundamental ProblemHTTP is stateless by design. Each request is independent. Statelessness enables scalability but requires explicit state management.
Where State LivesClient-side (URL, cookies, localStorage), server-side (sessions, DB, Redis), or hybrid (cookie holds ID, server holds data).
Mechanisms Comparison7 mechanisms differ in location, persistence, size limits, and security. No single mechanism fits all use cases.
When to Use WhatURLs for shareable state. Cookies for server-sent data. localStorage for persistence. sessionStorage for tab-scoped. Server sessions for security.
DemosHands-on examples for each mechanism. Inspect with DevTools to see state in action.
SecurityXSS reads localStorage. CSRF abuses cookies. Session fixation steals sessions. Always use HttpOnly, Secure, SameSite.
Decision GuideStart with the question: who needs this data and how sensitive is it? Auth → server sessions. Shareable → URL. Temporary → sessionStorage.