Web & Networking › How Browsers Work
IndexedDB
An asynchronous database built into browsers.
Also known as: indexeddb, indexed database, browser database
IndexedDB is the browser’s built-in NoSQL store: asynchronous, transactional, holding structured data (objects, files, blobs) far beyond localStorage’s 5MB string limit. Data lives in object stores (like tables) with indexes, inside versioned databases — and it survives reloads, working offline alongside service workers.
open db (version) → transaction → object store → get/put/index query
It’s genuinely a database: transactions with modes, cursors for iteration, indexes for queries, quotas in the hundreds of MB to GB. That power comes with the clunkiest grave-born API on the web platform — event-based requests wrapped by every sane project in a promise library.
The classic mistakes:
- Using localStorage for real data. Synchronous, tiny, string-only — localStorage blocks the main thread and fits tokens and prefs, not datasets. IndexedDB is the data store.
- Raw API without a wrapper. The event-based API multiplies code and bugs. Use a minimal promise wrapper; the raw API is a rite of passage nobody should repeat.
- Ignoring versions. Schema changes (new stores, indexes) happen in versioned upgrades only. Bumping versions and migrating is the whole schema story — plan it.
- One giant transaction. Long transactions across many stores block other tabs’ access and risk aborts. Keep transactions scoped and short.
- No quota handling. Storage can be evicted under pressure (especially “best effort” origins). Handle
QuotaExceededError, request persistence where it matters, and sync critical data server-side. - Assuming sync across devices. IndexedDB is per-browser, per-origin. Multi-device sync is a server problem — the local DB is a cache and offline buffer, not the system of record.
- Blocking on it at startup. Reads are async but still cost; don’t gate first paint on database opens that could lazy-load.
When to use it: offline-capable apps, large client datasets, caches and outbox queues. Small synchronous needs stay in localStorage; everything shaped like data belongs in IndexedDB.