LocalStorage QuotaExceededError behavior across browser engines
0 reputation · 18 Dec 2021, 23:04 UTC
0 reputation · 18 Dec 2021, 23:04 UTC
The HTML5 LocalStorage API provides a synchronous key-value store for persisting string data per origin. While most modern browsers implement a storage limit of approximately 5MB, the exact threshold and the resulting behavior when this limit is reached can vary.
When a setItem() operation exceeds the available capacity, the browser is expected to throw a QuotaExceededError. However, the precision of this limit and the consistency of the error trigger across different browser engines remain a point of uncertainty for applications requiring strict storage budget management.
QuotaExceededError consistently when the limit is reached during a sequence of multiple small writes versus one large write?35775 reputation · 19 Dec 2021, 08:17 UTC
The Web Storage specification does not define a 5 MB quota, nor does it specify whether the limit is measured in JavaScript characters or UTF-16 code units. It only requires that setItem() throw a QuotaExceededError DOMException when the key/value pair cannot be stored. In practice, engines account for the serialized key and value bytes plus internal storage overhead, so neither string.length nor UTF-16 byte length is a reliable quota unit.
For multiple writes, the behavior is consistent at the contract level but not at the threshold level: each setItem() is independent. The call that crosses the cumulative origin limit throws; earlier successful writes remain. There is no cross-setItem transaction, so many small records can exhaust the quota sooner than one large write because per-record overhead is repeated.
Confirmed by the specification:
localStorage is synchronous and scoped per origin.setItem() is an independent operation.DOMException whose name is 'QuotaExceededError'.Likely implementation detail (verify in your target runtime):
max(utf8Bytes(key+value), utf16Bytes(key+value)) plus a safety margin. There is no standard API that reports remaining localStorage bytes.if (e.name === 'QuotaExceededError'). After a throw, verify the failing key was not persisted.removeItem() the earlier keys you wrote in that logical operation.navigator.storage.estimate() only as an origin-wide signal. Its quota may include IndexedDB and Cache API usage and is not a localStorage-specific limit.Because exact thresholds are implementation-defined, verify in the exact browser engine and profile you support:
localStorage, then binary-search the largest single value accepted before QuotaExceededError. Record the exception name and compare the accepted length against UTF-8 and UTF-16 byte counts.navigator.storage.estimate() before and after the same writes, but treat the setItem failure point as authoritative.Which browser engine and version are you targeting? Quota behavior varies across engines, and private/incognito, mobile WebView, or low-storage conditions can lower or make quotas ephemeral. If you share the target runtime, the pre-check margin and rollback strategy can be tightened.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.