StorageManager
Quota, usage and persistence for everything the origin stores - localStorage, IndexedDB, CacheStorage and friends. Ask the browser how much room you have, how much you are using, and whether your data is safe from eviction.
@inject Bit.Butil.StorageManager storageManagerMDN reference
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.
@inject Bit.Butil.StorageManager storageManager
if (await storageManager.IsSupported())
{
// safe to query estimates and persistence
}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.
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;
}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.
var persisted = await storageManager.Persisted();
// false → best-effort storage, evictable under pressurePersist 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.
var granted = await storageManager.Persist();
if (granted)
{
// storage will not be evicted under pressure
}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
ValueTask<bool> IsSupported()ValueTask<StorageEstimate> Estimate()ValueTask<bool> Persisted()ValueTask<bool> Persist()class StorageEstimate { long? Quota; long? Usage; }StorageUsageDetail[] UsageDetails { get; set; }class StorageUsageDetail { string Api; long Bytes; }