StorageManager API: Query Storage Quota in JavaScript
The StorageManager API is a modern web platform feature that allows JavaScript applications to inspect available disk space, monitor current data consumption, and request persistent storage guarantees to prevent automatic browser data eviction. This article breaks down what the StorageManager API is, how web browsers categorize storage, and how to use its core JavaScript methods to inspect usage metrics and request persistent storage for applications relying on IndexedDB, Cache Storage, and other client-side storage systems.
What is the StorageManager API?
Web applications frequently store data locally using technologies such as IndexedDB, the Cache API, Web Locks, and OPFS (Origin Private File System). Traditionally, browsers managed this data with opaque limits, giving developers no native way to determine how much storage remained or whether the browser might purge their data under disk pressure.
The StorageManager API, accessible via
navigator.storage, provides programmatic access to the
browser’s storage subsystem for a specific origin. It provides two main
capabilities:
- Storage Estimation: Calculating total storage quota and current usage.
- Persistence Management: Determining whether data is treated as temporary or persistent, and requesting persistent status.
Storage Types: Best-Effort vs. Persistent
Browsers categorize origin data into two distinct storage modes:
- Best-Effort (Temporary): The default mode. The browser grants storage without asking the user, but it may clear this data automatically if the host device runs low on disk space (using a Least-Recently-Used eviction policy).
- Persistent: Data marked as persistent is exempt from automatic eviction. The browser will not delete it under low-disk conditions; it can only be removed if the user manually clears browsing data or uninstalls the application.
How to Query Storage Quota and Usage
To inspect how much data your origin is using and how much space is
available, use the navigator.storage.estimate() method.
This method returns a Promise that resolves to an object containing two
key properties:
usage: An estimate of the number of bytes currently used by the origin across all storage APIs.quota: An estimate of the maximum number of bytes available to the origin.
Example: Estimating Storage
async function checkStorageUsage() {
if ('storage' in navigator && 'estimate' in navigator.storage) {
try {
const { usage, quota } = await navigator.storage.estimate();
const usageInMB = (usage / (1024 * 1024)).toFixed(2);
const quotaInMB = (quota / (1024 * 1024)).toFixed(2);
const percentUsed = ((usage / quota) * 100).toFixed(2);
console.log(`Used: ${usageInMB} MB of ${quotaInMB} MB (${percentUsed}%)`);
} catch (error) {
console.error('Error estimating storage:', error);
}
} else {
console.warn('StorageManager estimate API is not supported in this browser.');
}
}
checkStorageUsage();Note: The returned numbers are estimates. Browsers intentionally add minor padding or approximations to prevent cross-site timing and fingerprinting attacks.
How to Check and Request Persistent Storage
You can verify whether your origin has been granted persistent
storage and request it if necessary using
navigator.storage.persisted() and
navigator.storage.persist().
Checking Persistence Status
async function isStoragePersisted() {
if ('storage' in navigator && 'persisted' in navigator.storage) {
const isPersisted = await navigator.storage.persisted();
console.log(`Storage persistence status: ${isPersisted ? 'Persistent' : 'Best-effort'}`);
return isPersisted;
}
return false;
}Requesting Persistent Storage
Calling persist() prompts the browser to upgrade the
origin’s storage from “best-effort” to “persistent”. Depending on the
browser and its heuristics (such as whether the site is installed as a
PWA, bookmarked, or frequently visited), this may automatically resolve
to true or trigger a browser permission prompt.
async function requestPersistence() {
if ('storage' in navigator && 'persist' in navigator.storage) {
const alreadyPersisted = await navigator.storage.persisted();
if (alreadyPersisted) {
console.log('Storage is already persistent.');
return true;
}
const granted = await navigator.storage.persist();
if (granted) {
console.log('Storage successfully set to persistent.');
} else {
console.log('Storage persistence request was denied.');
}
return granted;
}
return false;
}Best Practices
- Always Check Feature Availability: Ensure
navigator.storageand the required method exist before invoking them to avoid runtime errors on older or restricted environments. - Call
estimate()Before Large Writes: Before downloading large files or caching offline assets, queryestimate()to ensure sufficient quota is available. - Request Persistence Contextually: Call
persist()during a meaningful user interaction (such as enabling an “Offline Mode” switch or installing the app) to increase the likelihood that the browser or user approves the persistence grant.