Web Storage Table

–the three browser storage mechanisms compared
FeatureCookielocalStoragesessionStorage
Capacity~4 KB per cookie~5-10 MB per origin
Sent to serverYes, every requestNo
ExpirySet per cookie (Max-Age or Expires)Never (persistent until cleared)
Session expiryOptionalNo
Accessible from JSNot HttpOnly cookiesYes
APIdocument.cookie (string)localStorage.getItem/setItem
ScopeDomain + pathOrigin (protocol + domain + port)
Best forServer-side session ID, auth tokensUser preferences, cached data
The storage limits and behaviours follow MDN's Web Storage API reference (which covers localStorage and sessionStorage) and the Set-Cookie header specification. The critical security distinction: cookies with the HttpOnly flag cannot be read by JavaScript, which makes them the right choice for session tokens (protected from XSS); localStorage is always accessible to any script on the page, which makes it convenient but vulnerable to XSS exfiltration. Bottom line: use cookies with HttpOnly + Secure + SameSite for authentication tokens, and localStorage for non-sensitive UI state (theme preference, cached results) that improves the user experience without creating a security risk. Auth context: HTTP headers table for the Authorization and Set-Cookie headers, SHA-256 hash for integrity checks, chmod calculator for the server-side equivalent.

Browsers give you three ways to store data client-side: cookies (sent to the server on every request), localStorage (persistent, never sent) and sessionStorage (per-tab, cleared on close). Each has a different capacity, API and security model - and choosing wrong is either a performance problem (large cookies slow every request) or a security problem (sensitive data in localStorage is readable by any XSS payload).

The decision tree is simple: authentication tokens go in HttpOnly cookies (server needs them, XSS cannot read them), user preferences go in localStorage (never sent, survives restart), and per-tab state goes in sessionStorage (cleared when the tab closes).

How to use

  1. Filter by storage type (cookie, localStorage, sessionStorage) to see only the rows that affect that mechanism.
  2. Read the capacity row for the hard limit: cookies are ~4 KB each, localStorage is ~5-10 MB per origin.
  3. Check the "sent to server" row: cookies travel with every HTTP request (performance cost), localStorage and sessionStorage never leave the browser.

Frequently asked questions

What is the difference between sessionStorage and localStorage?

sessionStorage is per-tab and cleared when the tab closes - useful for form state or one-time tokens. localStorage persists across tabs and browser restarts - useful for theme preferences, cached API responses and shopping carts. Both have the same API (getItem/setItem/removeItem) and the same ~5-10 MB limit.

What is the HttpOnly flag and why does it matter?

HttpOnly is a Set-Cookie attribute that prevents JavaScript from reading the cookie via document.cookie. Without it, any XSS vulnerability lets an attacker steal the session token and impersonate the user. With it, the cookie is still sent with every HTTP request (so the server can authenticate) but is invisible to JavaScript - the single most effective XSS mitigation for session security.

How much can I actually store in localStorage?

Browsers allocate 5-10 MB per origin (protocol + domain + port). This is string-only storage - objects must be JSON.stringify-ed first. If you exceed the limit, setItem throws a QuotaExceededError. For larger data, use IndexedDB (hundreds of MB) or the Cache API.

What happens when I exceed the cookie size limit?

The browser silently drops the cookie or refuses to set it - there is no error thrown. Since all cookies for a domain are sent with every request, the total across all cookies for one domain should stay under 4 KB. Exceeding it means the server never receives the data you thought you stored.

Related tools