Part III β The Speed Β· Lesson 6.1
Database & Caching Overview
In one lineThe browser has five storage tiers β pick by size, lifetime, and who else needs to read it.
Where you've seen itA mail client holding a theme preference, an unsent draft, a session token, and a full offline mailbox β four different stores, deliberately.
Diagram
THE TIERS β fastest and smallest at the top
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Memory (JS variables, store) 0ms dies on reload β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β sessionStorage ~5MB sync dies with the tab β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β localStorage ~5MB sync forever, sync API β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Cookies 4KB sync SENT TO SERVER β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β IndexedDB GBs async forever, structuredβ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Cache Storage (SW) GBs async Request/Response β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β HTTP cache (browser-managed) β you control it with β
β CDN edge cache headers, not with code β
β Origin / real database β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββTHREE QUESTIONS THAT PICK THE TIER
1. How big? > 5MB ββΊ IndexedDB / Cache Storage
2. How long? this tab only ββΊ sessionStorage
across visits ββΊ localStorage / IndexedDB
3. Who reads it? the server ββΊ cookie (it's the only one sent)
only JS ββΊ anything elseCACHING'S TWO HARD PARTS
1. WHAT to cache cheap to decide
2. WHEN to invalidate the actual problem
stale data ββββββββββββββββΊ extra requests
(wrong) (slow)
Every strategy in this chapter is a position on that line.How it works
- Start from lifetime. Data that must not outlive the tab goes in
sessionStorage; everything longer-lived needs a deliberate invalidation story. - Never put secrets in web storage β any XSS reads all of it instantly (see 3.5).
- Prefer async storage for anything sizeable.
localStorageis synchronous and blocks the main thread, which shows up directly in INP. - Version your stored shapes. Old data in a new app is a crash waiting to happen β store a schema version and migrate or discard.
- Assume it can vanish. Storage is evictable under pressure and users clear it; treat every cache as an optimisation, never as the source of truth.
Trade-offs
| Store | Size | Sync? | Sent to server | Good for |
|---|---|---|---|---|
| Memory | RAM | sync | no | Derived/session state |
sessionStorage | ~5MB | sync | no | Per-tab drafts, wizards |
localStorage | ~5MB | sync | no | Small prefs, flags |
| Cookies | 4KB | sync | yes | Auth, server-read state |
| IndexedDB | GBs | async | no | Offline data, big lists |
| Cache Storage | GBs | async | no | Requests/responses (SW) |
Interview angle
"Where would you cache the user's feed?"
- Three layers: HTTP cache for the assets, an in-memory client cache for the current session, and IndexedDB for offline availability.
- Normalise entities (6.6) so one updated post updates everywhere rather than in three copies.
- Then state the invalidation rule explicitly β TTL, ETag revalidation, or event-driven purge β because that's the part that actually gets asked about.
Recap
- Size, lifetime, and audience pick the tier; nothing else matters much.
- Cookies are the only store the server sees, and they cost bytes on every request.
- Caching is easy; invalidation is the design decision worth defending.