Lesson 0005 · ~14 minutes
One skill: run a 60-second design-review scan — when IndexedDB is the wrong tool, and which production edges kill “just store it in IDB.”
You can reject a bad storage proposal quickly (wrong API, “durable forever,” no migration plan, multi-tab blindness) and green-light a good one with eyes open on quota and sync policy.
You’ve been lesson-first — fine. This page is self-contained for the quiz. If you want one high-value skim later: web.dev Storage for the web (quota / eviction / spectrum) or MDN storage limits.
| Requirement | Usually not IDB | Prefer |
|---|---|---|
| HTTP assets / app shell offline | Object stores of Responses | Cache API (+ SW) |
| Tiny flags, sync, main-thread only | Full IDB ceremony | Memory / careful Web Storage |
| File-shaped bytes, editor blobs | Keyed records only | OPFS (or Blob in IDB if record-shaped) |
| Auth tokens on every request | IDB as cookie substitute | HttpOnly cookies / proper auth design |
| Multi-device source of truth | “IDB will sync itself” | Server + explicit sync policy |
Lesson 1 spectrum still applies: IDB wins for durable structured app data on this origin — not as a general kitchen sink.
Browser storage is typically best-effort under pressure. Origins share a quota pool (IDB + Cache + other site data). When the device is low on space, browsers may evict site data — often least-recently-used origins first. Exact numbers and policies differ by browser and change over time; design for “may vanish,” not for a fixed 50 MB SLA.
navigator.storage.estimate() — usage vs quota (approx).
navigator.storage.persist() — request
persistent storage (user/permission dependent; not
universal immortality).
Treat long-lived client data on iOS Safari as especially hostile: storage can be capped or cleared under inactivity and privacy policies. Never pitch “offline forever on the user’s phone” without a server fallback and re-hydration path. (Details evolve — verify current WebKit / MDN notes before a hard product claim.)
From lessons 2–4: version bumps, upgrade-only store/index creation,
multi-tab versionchange / blocked. In a
design review, “we’ll refactor the IDB shape next sprint” implies:
oldVersion still in the wild.If the team cannot own that ceremony, keep the schema tiny and stable — or don’t put the feature in IDB yet.
Multiple connections (tabs, workers) can read and write. Transactions serialize writers on overlapping stores, but product conflicts are yours: last write wins, optimistic versions, “open in two tabs and edit the same draft.” IDB does not give you CRDTs or presence.
BroadcastChannel,
storage events (Web Storage only), or custom messaging —
not automatic IDB change feeds in all browsers historically (design
for explicit refresh/invalidate).
await fetch mid-transaction → inactive/finished errors
(lesson 3). Keep IDB work contiguous.
IDB is async, but huge getAll + heavy decode on main
still janks. Page big work; consider workers (you already know that
track).
idb / Dexie improve ergonomics; they don’t remove
quota, upgrade, or multi-tab product design.
IndexedDB is a local store. Offline queues, conflict resolution, tombstones, and “server always wins” are features you design. Shipping IDB without answering who is the source of truth when the network returns? is a deal-breaker for multi-device products.
Wrong tool? · Survive eviction / clear-data? · Schema migration owned? · Multi-tab writers / upgrades? · Txn lifetime safe? · Sync policy explicit? · Main-thread cost bounded?
equal-length choices. Immediate feedback.
Product wants offline HTML/JS/CSS for the app shell. First store to reach for?
Design review claim: “Once written to IndexedDB it can never disappear until we delete it.” Your response?
Team wants to rename fields and add three indexes in next release. What must be in the plan?
“Two devices edit the same draft offline; both come online.” Who resolves the conflict?
Which integration pattern is a hard red flag?
Still optional if you want to stay lesson-only. Best next reads when you choose to: