How the Browser Stores State

Chapter 1
How the Browser Stores State
Cookies, localStorage, sessionStorage, and IndexedDB — what each one is actually for, compared side by side

HTTP itself has no memory — every request to a server is, by design, completely independent of the last. Everything that makes a website feel "stateful" (staying logged in, remembering a shopping cart, keeping a dark-mode preference) depends on the browser storing something locally between requests. There are four main ways it does this, and this chapter is about understanding which tool fits which job — a distinction that gets directly relevant in later chapters covering cookie attributes, tracking prevention, and the real browser warning that prompted this course.

The Four Storage Mechanisms

🍪 Cookies
The oldest mechanism — small pieces of text, automatically sent back to the server with every matching HTTP request. The only storage type the server can both set and read directly.
📦 localStorage
A simple key-value store, accessible only via JavaScript, that persists indefinitely until explicitly cleared. Never sent to the server automatically.
📋 sessionStorage
Identical API to localStorage, but scoped to a single tab — cleared the moment that tab or window closes. Useful for state that genuinely shouldn't outlive the current visit.
🗄️ IndexedDB
A genuine client-side database — structured, queryable, capable of storing much larger and more complex data than the other three. Overkill for a simple preference flag, essential for offline-capable apps.

Seeing Each One in Practice

Cookies — set via JavaScript or an HTTP response header

// JavaScript
document.cookie = "theme=dark; path=/; max-age=2592000";

// Or set by the server in an HTTP response header (more common in practice):
Set-Cookie: theme=dark; Path=/; Max-Age=2592000

localStorage and sessionStorage — JavaScript only

localStorage.setItem('theme', 'dark');
localStorage.getItem('theme'); // "dark"

sessionStorage.setItem('formDraft', 'unsaved comment text...');
// Gone the moment this tab closes

IndexedDB — a real, asynchronous database API

const request = indexedDB.open('MyAppDB', 1);
request.onsuccess = (event) => {
  const db = event.target.result;
  // transactions, object stores, indexes — a real database, in the browser
};
IndexedDB gets its own deeper coverage later
This chapter introduces IndexedDB just enough to place it correctly in the comparison below — full usage patterns (object stores, transactions, indexes) are out of scope for this introductory chapter and better suited to a dedicated frontend/PWA-focused course if Philip wants one later.

Side-by-Side Comparison

PropertyCookieslocalStoragesessionStorageIndexedDB
Sent to server automatically? Yes, every request No No No
Accessible via JavaScript? Yes, unless HttpOnly Yes Yes Yes
Typical size limit ~4KB per cookie ~5–10MB ~5–10MB Hundreds of MB+ (browser-dependent)
Persists after tab closes? Until expiry, if set Yes, indefinitely No Yes, indefinitely
Data structure Simple strings Key-value strings Key-value strings Structured objects, indexed
API style document.cookie / headers Synchronous Synchronous Asynchronous

Choosing the Right One

NeedUse
The server needs to know this value on every request (e.g. a session ID)Cookies
A user preference that should persist across visits, purely client-side (e.g. dark mode)localStorage
Temporary state that shouldn't survive closing the tab (e.g. a multi-step form's draft)sessionStorage
A genuinely large or structured dataset the app needs offline (e.g. cached articles, an offline-capable app's data)IndexedDB
Don't default to cookies just because they're familiar
Cookies are the only mechanism the server needs for session identification — but storing things like UI preferences or form drafts in cookies wastes bandwidth, since every cookie gets sent on every single request to that domain, including requests for images and stylesheets that don't need that data at all. localStorage is almost always the better choice for anything purely client-side.

Looking Ahead in This Course

This comparison sets up everything that follows: Chapter 2 goes deep into cookie attributes specifically (since cookies are the most complex of the four, with real security implications). Chapter 3 covers first-party vs third-party cookies, and Chapter 4 finally explains the actual mechanism behind the real browser warning that prompted this course — "the state of osztromok.com was recently purged because it was detected as a bounce tracker."

Chapter 1 Quick Reference

  • Cookies — the only one automatically sent to the server; small (~4KB); accessible via JS unless HttpOnly
  • localStorage — JS-only, persists indefinitely, ~5-10MB, simple key-value strings
  • sessionStorage — same API as localStorage, but cleared when the tab closes
  • IndexedDB — a real async database in the browser; large capacity, structured data
  • Rule of thumb: server needs it → cookie; client-only preference → localStorage; tab-scoped draft → sessionStorage; large/structured offline data → IndexedDB
  • Next chapter: cookies in depth — Domain, Path, Expires, Secure, HttpOnly, SameSite