v145 · Web APIs · Storage
IndexedDB: SQLite backend (in-memory contexts)
Chrome 145 ships a SQLite-backed implementation of IndexedDB for in-memory contexts — private browsing, opaque origins, and storage partitions — replacing the legacy LevelDB backend for these cases.
background
Chrome's IndexedDB has historically used LevelDB as its storage backend. A parallel SQLite backend was developed for improved reliability and consistency. Chrome 145 switches in-memory contexts (incognito, opaque origins) to the SQLite backend first, since these contexts hold no persistent data and the migration carries no data-loss risk.
From a web developer perspective, IndexedDB behaviour is unchanged — the switch is internal. This is a stepping stone toward moving all persistent IndexedDB storage to SQLite in a future release.
concepts
-
IDB Demo
Creates an IndexedDB database, writes and reads records, and checks storage estimates — works identically whether backed by LevelDB or SQLite, demonstrating the transparent migration.
-
Memory Context Guide
What counts as an in-memory context, how storage APIs behave in incognito and opaque origins, and the difference between temporary and persistent storage partitions.
-
Perf Comparator
Benchmark bulk insert, point gets, range cursors, and full scans against an in-memory IDB store, and watch the latency curve change shape under the SQLite backend.
-
Storage Context Probe
Runs a battery of storage API tests — IndexedDB, quota, persistence, Cache API, localStorage — to characterise the current context. Demonstrates that IndexedDB now works in incognito (SQLite backend in Chrome 145) and explains which incognito detection methods still work and which don't.
the change
// No API change — IndexedDB works identically.
// The backing store (SQLite vs LevelDB) is transparent.
const db = await new Promise((resolve, reject) => {
const req = indexedDB.open('my-db', 1);
req.onupgradeneeded = e => {
e.target.result.createObjectStore('items', { keyPath: 'id' });
};
req.onsuccess = e => resolve(e.target.result);
req.onerror = e => reject(e.target.error);
});
// Write
const tx = db.transaction('items', 'readwrite');
tx.objectStore('items').put({ id: 1, name: 'hello' });
// Read
const tx2 = db.transaction('items', 'readonly');
const req = tx2.objectStore('items').get(1);
req.onsuccess = () => console.log(req.result);
// Works in incognito (now SQLite-backed in Chrome 145),
// in opaque origins (sandboxed iframes), and normal contexts (LevelDB for now).