Asyncintermediate
Web Storage vs Cookies for Async Data
How localStorage, sessionStorage, and cookies differ in capacity, lifetime, and how they interact with server requests, relevant when caching async fetch results client-side.
Three ways to keep data in the browser, with different lifetimes and different relationships to the server.
localStorage is a filing cabinet in your own office that never gets cleaned until you do it. sessionStorage is a rented office cleared out when you leave. Cookies are a name badge you wear to every meeting automatically.
Key Concepts
1
localStorage ~5-10 MB, persists until cleared,
per origin, never sent to the server
sessionStorage same, cleared when the tab closes,
per tab
cookies ~4 KB, sent with EVERY request to the domain2
The size and the automatic sending are the two decisions.
localStorage.setItem('theme', 'dark');
localStorage.getItem('theme');3
Storage is synchronous and string-only, so objects need JSON.stringify both ways — and a large item read
on every render blocks the main thread.
JSON.stringify
4
Cookies go to the server whether you want them to or not. A 3 KB cookie adds 3 KB to every request,
including images and scripts on that domain.
5
Which is why they are for things the server needs — session identifiers — and not for client state.
6
document.cookie = 'token=abc; Secure; HttpOnly; SameSite=Strict';7
HttpOnly is the security point. A cookie marked HttpOnly cannot be read by JavaScript, so an XSS
flaw cannot steal it.
HttpOnly
8
localStorage has no equivalent. Anything in it is readable by any script on the page, including an
injected one — which is the argument against keeping authentication tokens there.
localStorage
9
Caching fetch results. localStorage suits it, with an expiry you enforce yourself:
localStorage
10
const cached = JSON.parse(localStorage.getItem(key) || 'null');
if (cached && Date.now() - cached.at < 300000) return cached.data;11
const data = await fetch(url).then(r => r.json());
localStorage.setItem(key, JSON.stringify({ at: Date.now(), data }));12
Nothing expires on its own, so an entry written a year ago is still there.
13
When storage is the wrong tool.
IndexedDB large or structured data, asynchronous, indexed
Cache API HTTP responses, used by service workers14
localStorage being synchronous is its real limitation: a few hundred kilobytes read at startup is
measurable jank.
localStorage
15
And the ones that fail quietly. Private browsing and blocked site data can make storage throw or return
nothing. Every read and write belongs in a try/catch, with the page working when it returns nothing —
otherwise a privacy setting becomes a blank screen.
try/catch
16
What the interviewer is probing.1. "When would you use a cookie rather than localStorage?" Probing: the deciding property.
Stalls: "They are the same." Moves up: when the server needs the value on every request, since
cookies are sent automatically — and an httpOnly cookie is not readable by script.
17
2. "Why is localStorage a poor place for a token?" Probing: the security argument. Stalls:
"It is convenient." Moves up: any XSS can read it; an httpOnly, Secure, SameSite cookie cannot be
read by injected script.
18
3. "What are the limits?" Probing: the practical caps. Stalls: "Unlimited." Moves up:
about 4KB per cookie and roughly 5–10MB for localStorage, which is synchronous and blocks the main
thread on large reads.
19
4. "When do you reach for IndexedDB?" Probing: the third option. Stalls: "Never." *Moves
up:* larger structured data, binary blobs, or when you need asynchronous access and indexes rather
than a string key-value store.