Browser Storage Failure Modes
Browser offline storage is durable enough for serious apps only when you design for quotas, eviction, upgrades, and multiple tabs.
Failure Table
| Failure | Symptom | Mitigation |
|---|---|---|
| quota exceeded | writes fail | catch errors, show cleanup/export UX, compress or prune caches |
| best-effort eviction | data disappears under pressure | request persistent storage and keep backup/export path |
| blocked upgrade | new app version cannot open DB | detect blocked upgrade and ask user to close other tabs |
| versionchange in old tab | old tab keeps using stale schema | listen for version changes and reload/close old connection |
| private mode | data clears when session ends | warn users before storing durable-only data |
| large export | UI freezes | use worker-backed export/import |
| background sync unavailable | queued writes stay pending | retry on foreground app open |
Persistence Request
export async function requestPersistentStorage() {
if (!navigator.storage?.persist) return false;
return navigator.storage.persist();
}
Persistence is not a backup. It only changes eviction behavior when the browser grants it.
Upgrade Blocking
db.on("blocked", () => {
showReloadOtherTabsMessage();
});
Test this with two tabs open: one old tab holding a connection, one new tab trying to upgrade.