Skip to content

Concept in Storage

Storage quotas, persistence, and eviction

Published

Widely available since 2021-12WHATWG living standard

Storage quota limits how much an origin can write, persistence primarily changes whether its bucket is eligible for automatic clearing, and eviction removes stored data under a browser’s clearing policy. Quota remains implementation-defined and can depend on persistent-storage permission, so a successful persistence request may also change the origin’s quota. Firefox, for example, applies a higher limit after persistent storage is granted.

The compatibility table for this entry uses the api.StorageManager.persist data in Persistent Storage.

The Storage Standard gives each storage shelf a default bucket. A local storage bucket’s mode is best-effort or persistent. It defines usage as an implementation-defined rough estimate and quota as an implementation-defined conservative estimate. Compression, deduplication, and privacy protections mean the values returned by estimate() are not an exact view of disk blocks (Storage Standard, storage.spec.whatwg.org).

Persistence protects a local storage bucket from clearing by the user agent without involvement from the origin or user. The standard still permits the user to clear it. The persist() method requests the persistent-storage permission and resolves to a boolean that reports whether the default bucket is persistent; persisted() reads that mode without requesting a change (Storage Standard, storage.spec.whatwg.org).

Eviction applies to storage the browser manages by origin, including IndexedDB, Cache Storage, and the Origin Private File System. When a browser evicts an origin, MDN documents that it deletes the origin’s managed data together instead of trimming one database. The Storage Standard likewise requires a bucket to be cleared in its entirety (Storage quotas and eviction criteria, developer.mozilla.org; Storage Standard, storage.spec.whatwg.org).

Decision Question to answer Browser signal Application response
Quota Can the next write fit? navigator.storage.estimate() gives approximate usage and quota. Catch the write error and offer cleanup or server recovery.
Persistence May the browser automatically clear this bucket? persisted() reports the mode; persist() requests a change. Keep critical local-only work recoverable until the result is true.
Eviction What happens when the browser needs space? There is no eviction event in the Storage Standard. On startup, validate the records and caches the app needs, then rebuild missing data.

Chrome’s storage guidance states that Chrome lets the browser use up to 80% of total disk space and lets an origin use up to 60%. It also states that best-effort origins are cleared in least-recently-used order when the browser runs out of space. Those figures describe Chrome’s policy, while other Chromium-based browsers can differ (Storage for the web, web.dev).

Chrome and other Chromium browsers normally decide a persistence request from site-engagement signals without showing a permission prompt. A returned false leaves the bucket in best-effort mode; it does not mean that a write has failed (Storage quotas and eviction criteria, developer.mozilla.org).

MDN records Firefox best-effort storage as the smaller of 10% of the disk that holds the profile or the 10 GiB group limit shared by origins in the same site. Persistent origins can use up to 50% of total disk, capped at 8 TiB, and are not subject to that group limit. Firefox asks the user when a site requests persistent storage. Under storage pressure, it skips persistent origins and evicts best-effort origins in least-recently-used order (Storage quotas and eviction criteria, developer.mozilla.org).

Firefox calculates the quota from total disk size. An origin can therefore receive an estimate larger than the space that can actually be written. Code still needs to handle a failed write after a reassuring estimate.

WebKit documents separate origin and overall quotas. Starting in Safari 17.0 and WebKit apps for iOS 17, iPadOS 17, and macOS Sonoma, a browser app’s origin quota is up to 60% of total disk and its overall quota is up to 80%. Other apps that embed web content receive lower limits. A standalone Home Screen web app on iOS or a web app added to the Dock on macOS receives the same origin and overall quota as the site in a browser app (Updates to Storage Policy, webkit.org).

WebKit names overall-quota pressure, system storage pressure, and Intelligent Tracking Prevention as paths that can delete website data. Its ITP documentation says that, from iOS and iPadOS 13.4 and Safari 13.1 on macOS, seven days of Safari use without interaction with a site causes deletion of its script-writable storage. Home Screen web apps have their own counter of days of use (Full Third-Party Cookie Blocking and More, webkit.org).

The first example reports the mode and the estimate without treating either value as a promise that a later write will succeed.

async function readStorageState() {
if (!navigator.storage?.estimate) {
return { supported: false, persisted: false };
}
const { usage = 0, quota = 0 } = await navigator.storage.estimate();
const persisted = navigator.storage.persisted
? await navigator.storage.persisted()
: false;
return { supported: true, usage, quota, persisted };
}
readStorageState().then((state) => console.log(state));

The fallback returns a state the interface can label as unavailable. When support exists, usage and quota remain estimates in bytes; the application can display them without deriving a guaranteed amount for its next transaction.

The second example requests persistence and handles a quota failure separately. It preserves the draft on the server when local storage cannot accept it.

async function saveDraft(draft) {
const persistent = navigator.storage?.persist
? await navigator.storage.persist()
: false;
try {
await draftsDatabase.put(draft);
return { saved: 'local', persistent };
} catch (error) {
if (error?.name !== 'QuotaExceededError') throw error;
await fetch('/api/drafts', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify(draft),
});
return { saved: 'server', persistent };
}
}

The persistence result and the write result stay independent. A false persistence result can accompany a successful write, while QuotaExceededError takes the explicit recovery branch described by Chrome’s and WebKit’s storage guidance.

On the next launch, check for application-level records. estimate() alone cannot identify eviction. A missing database can also mean a first visit or a user-initiated clear. Eviction and best-effort storage covers that recovery boundary, and Safari’s 7-day cap on script-writable storage covers WebKit’s proactive path.

Specifications

SpecificationStatus
Persistent StorageWHATWG living standard
  • Legend
  • Yes
  • Partial
  • Flag
  • No
  • Unknown
Browser / PlatformSupportVersionsConfidenceSourceNotes
Chrome (Desktop)#Yes55highsource—
Chrome (Android)#Yes55highsource1
Edge (Desktop)#Yes79highsource2
Firefox (Desktop)#Yes57highsource—
Firefox (Android)#Yes57highsource3
Safari (macOS)#Yes15.2highsource—
Safari (iOS)#Yes15.2highsource4
Samsung Internet#Yes6.0highsource5
WebView (Android)#Yes55highsource6
  1. Derived by browser-compat-data mirroring from Chrome.
  2. Derived by browser-compat-data mirroring from Chrome.
  3. Derived by browser-compat-data mirroring from Firefox.
  4. Derived by browser-compat-data mirroring from Safari.
  5. Derived by browser-compat-data mirroring from Chrome Android.
  6. Derived by browser-compat-data mirroring from Chrome Android.

Source data: /compatibility/persistent-storage.json · Global usage: 96 % (StatCounter 2026-09, CC BY-SA 4.0)

Source: spec · MDN · Last verified 2026-10-03 · Confidence: high (computed from sources)