v145 · Web APIs · Storage · demo

Storage Context Probe

Runs a battery of storage API tests to characterise the current browsing context — IndexedDB availability, quota estimates, persistence, and Cache API access. The key consequence of Chrome 145's SQLite backend: IndexedDB now works reliably in in-memory contexts (incognito), making IDB-based incognito detection unreliable.

Chrome 145: IndexedDB uses a SQLite backend in in-memory contexts (incognito, opaque origins). The API surface is unchanged — the switch is internal. The main developer-visible consequence is that IDB-based incognito probes no longer work.

Click "Run probe" — then open in an incognito window and compare results · try both contexts

Click to probe storage APIs in this context
Incognito detection methods — what changed in Chrome 145
IDB write/read probe Broken in Chrome 145+ — IDB now works in incognito (SQLite backend). Previously it would throw or return null.
storage.estimate() quota Unreliable — quota varies by device. Incognito has lower cap (~120 MB vs unlimited) but this threshold changes with storage pressure.
storage.persist() Returns false in incognito (persistence never granted). Not definitive — users can also deny it in normal context.
FileSystem Access API Limited in incognito. File picker works but OPFS is in-memory only — harder to probe reliably.
Don't detect it Best practice — let users browse privately without interference. Chrome actively closes incognito detection loopholes.
// Chrome 145: IndexedDB uses SQLite in incognito — the API is unchanged.
// This classic incognito-detection pattern no longer works:

// BROKEN in Chrome 145+ (don't use this):
function isIncognito_OLD() {
  return new Promise(resolve => {
    const req = indexedDB.open('test');
    req.onerror = () => resolve(true);  // Previously failed in incognito
    req.onsuccess = () => resolve(false);
  });
}

// What you CAN still check (but these are heuristics, not reliable):
const estimate = await navigator.storage.estimate();
const lowQuota = estimate.quota < 130_000_000; // incognito cap ~120 MB

const persisted = await navigator.storage.persist();
// Returns false in incognito — but also false if user denies the prompt

// Best practice: do not detect incognito.
// Design features to work well regardless of storage context.

see also