Keeping critical web app data safe from eviction

Browsers typically respond to storage pressure—such as low disk space—by evicting data from the least recently used origin, including data in the Cache API and IndexedDB. For an app that hasn't synced data to a server, this can cause significant data loss, and even for synced apps, eviction removes resources needed for the app to function. Both outcomes result in a poor user experience.

Research by the Chrome team, however, shows that Chrome rarely clears stored data automatically. User-initiated manual storage clearing is far more common. As a result, if users visit your site regularly, eviction is unlikely. Still, for critical data, you can request that your entire site's storage be marked as persistent, which prevents the browser from deleting it. Persistent storage is supported in many modern browsers.

Check current persistence status

To determine whether your site's storage has already been marked as persistent, call navigator.storage.persisted(). This method returns a Promise that resolves to a boolean indicating the persistence state.

// Check if site's storage has been marked as persistent
if (navigator.storage && navigator.storage.persist) {
  const isPersisted = await navigator.storage.persisted();
  console.log(`Persisted storage granted: ${isPersisted}`);
}

Choosing the right moment to request persistence

The ideal time to request persistent storage is when you are about to save critical user data, and the request should be wrapped in a user gesture. Do not make the request during page load or other bootstrap code. A permission prompt shown when the user isn't expecting it—because they haven't done anything they consider worth saving—will likely be confusing and rejected. Similarly, avoid prompting too frequently: if a user denies the request, do not ask again on the very next save operation.

Requesting persistent storage

To request persistence for your site's data, call navigator.storage.persist(). Like persisted(), it returns a Promise that resolves to a boolean indicating whether the persistent storage permission was granted.

// Request persistent storage for site
if (navigator.storage && navigator.storage.persist) {
  const isPersisted = await navigator.storage.persist();
  console.log(`Persisted storage granted: ${isPersisted}`);
}

How permission decisions are made

Persistent storage is treated as a permission, and browsers use different criteria to decide whether to grant it.

Chrome and Chromium-based browsers

Chrome and most other Chromium-based browsers evaluate the request automatically, without showing any prompt to the user. The permission is granted silently if the site is deemed important, and silently denied otherwise. The heuristics used include:

  • The level of site engagement.
  • Whether the site is installed or bookmarked.
  • Whether the site has been granted notification permission.

A denied request can be made again later and will be evaluated using the same heuristics.

Firefox

Firefox delegates the decision to the user. When persistent storage is requested, the browser displays a UI popup asking whether the site may store data persistently.

A popup shown by Firefox when a site requests persistent storage.
A popup shown by Firefox when a site requests persistent storage.

What persistent storage protects

When the persistent storage permission is granted, the browser will not evict data stored in:

  • Cache API
  • Cookies
  • DOM Storage (Local Storage)
  • File System API (browser-provided and sandboxed file system)
  • IndexedDB
  • Service workers
  • App Cache (deprecated)
  • WebSQL (deprecated)

Releasing persistent storage

There is currently no programmatic way to tell the browser that you no longer need persistent storage.

Final thoughts

While stored data is rarely cleared automatically by Chrome, persistent storage is a valuable safeguard for critical data that isn't backed up in the cloud or whose loss would be especially disruptive. Request it at the moment the user is most likely to want it—when they're saving something they care about—not arbitrarily at startup.