loading

Check for support

IsSupported

navigator.storage requires a secure context (HTTPS or localhost) and is absent in some older or embedded browsers, so feature-detect before showing quota UI.

C#
@inject Bit.Butil.StorageManager storageManager

if (await storageManager.IsSupported())
{
    // safe to query estimates and persistence
}
Live sample
support output
Results will appear here when you interact with the samples.

Quota and usage estimate

Estimate

Estimate reports how many bytes the origin is currently using and roughly how many it may use in total, across all storage backends. The numbers are deliberately imprecise - browsers pad them to resist fingerprinting - but they are exactly what you need for a storage meter or a pre-download space check.

C#
var estimate = await storageManager.Estimate();

// values in bytes; null when the runtime can't report them
var usage = estimate.Usage;
var quota = estimate.Quota;

if (usage is not null && quota is not null)
{
    var percent = (double)usage.Value / quota.Value * 100;
}
Live sample
estimate output
Results will appear here when you interact with the samples.

Is storage persistent?

Persisted

By default an origin's storage is best-effort: under disk pressure the browser may silently evict it. Persisted tells you which mode you are in - true means the data will survive until the user or the app explicitly deletes it.

C#
var persisted = await storageManager.Persisted();
// false → best-effort storage, evictable under pressure
Live sample
persisted output
Results will appear here when you interact with the samples.

Request persistence

Persist

Persist asks the browser to upgrade the origin to persistent storage. The user agent decides: Chromium grants silently based on engagement heuristics (bookmarks, install state, notification permission), Firefox prompts the user. A false result is normal for a site the user has barely interacted with - it is a request, not a command.

C#
var granted = await storageManager.Persist();

if (granted)
{
    // storage will not be evicted under pressure
}
Live sample
persist output
Results will appear here when you interact with the samples.
Note:
One quota for everything The estimate covers the origin's combined footprint: IndexedDB databases, CacheStorage caches, service-worker registrations and Origin Private File System data all draw from the same budget. Web Storage (localStorage / sessionStorage) has its own separate ~5 MB cap in most browsers.
Warning:
Estimates are estimates Browsers intentionally round and pad the reported values to prevent them being used as a fingerprinting signal or an eviction oracle. Treat Usage and Quota as order-of-magnitude guidance, not accounting-grade numbers - and both can be null when the runtime cannot report them.

API reference

Member
Signature
Description
IsSupported
ValueTask<bool> IsSupported()
True when the runtime exposes navigator.storage.
Estimate
ValueTask<StorageEstimate> Estimate()
Reports an estimate of the storage quota and current usage for the origin.
Persisted
ValueTask<bool> Persisted()
True when the origin's storage is persistent (won't be evicted under pressure).
Persist
ValueTask<bool> Persist()
Asks the browser to make storage persistent. The user agent decides whether to grant.
StorageEstimate
class StorageEstimate { long? Quota; long? Usage; }
Estimate payload. All values are in bytes; null when the runtime can't report them.
StorageEstimate.UsageDetails
StorageUsageDetail[] UsageDetails { get; set; }
Per-API breakdown of Usage - which storage API holds the bytes (indexedDB, caches, serviceWorkerRegistrations, ...). Empty outside Chromium, so treat empty as unknown rather than as nothing stored.
StorageUsageDetail
class StorageUsageDetail { string Api; long Bytes; }
One entry of the usage breakdown.
An unhandled error has occurred. Reload 🗙