What Happens When Localstorage Is Full

What happens when localStorage is full?

Firstly, some useful resources:

  • Web
    Storage Support Test - has a table comparing data storage quotas
    between browsers.
  • Simple
    localStorage quota test
  • Summary of localStorage browser behaviour
  • W3C spec - indicating how a user agent (e.g. browser) should behave (both localStorage and sessionStorage).

In answer to your question, desktop browsers tend to have an initial maximum localStorage quota of 5MB per domain. This can be adjusted by the user in some cases:

  • Opera: opera:config -> Domain Quota For localStorage
  • Firefox: about:config -> dom.storage.default_quota

In Chrome, there doesn't seem to be a way for the user to adjust this setting although like Opera, localStorage data can be edited directly per domain using the Developer Tools.

When you try to store data in localStorage, the browser checks whether there's enough remaining space for the current domain.
If yes:

  • The data is stored, overwriting values if an identical key already exists.

If no:

  • The data is not stored and no existing data is overwritten.
  • A QUOTA_EXCEEDED_ERR exception is thrown.

In this case, getItem(key) will return the last value that was successfully stored, if any.

(Opera is slightly different in that it displays a dialog box giving the user the choice of increasing storage space for the current domain.)

Note that sessionStorage and localStorage are both implementations of the same Storage object so their behaviour is similar and error handling is the same.

What happens when local / Session Storage is full?

If storage is full when you try to add something to it, according to the specification the method that's adding the new/updated item must throw a QuotaExceededError. So your app/page will work just fine if storage is full but if it tries to add anything, that action will fail with an error.

From that link:

The setItem(key, value) method must first check if a key/value pair with the given key already exists in the list associated with the object.

If it does not, then a new key/value pair must be added to the list, with the given key and with its value set to value.

If the given key does exist in the list, and its value is not equal to value, then it must have its value updated to value. If its previous value is equal to value, then the method must do nothing.

If it couldn't set the new value, the method must throw a QuotaExceededError exception. (Setting could fail if, e.g., the user has disabled storage for the site, or if the quota has been exceeded.)

(my emphasis)

LocalStorage - detect if local storage is already full

Upon attempting to add to localstorage, if there is not enough space, this error will be thrown. In you particular scenario, you could use this event to free up some space.

try {
localStorage.setItem("name", "Hello World!"); //saves to the database, "key", "value"
} catch (e) {
if (e == QUOTA_EXCEEDED_ERR) {
alert('Quota exceeded!'); //data wasn't successfully saved due to quota exceed so throw an error
}
}

credit to - http://chrisberkhout.com/blog/localstorage-errors/

When is localStorage cleared?

W3C draft says this

User agents should expire data from the local storage areas only for security reasons or when requested to do so by the user. User agents should always avoid deleting data while a script that could access that data is running.

So if browsers follow the spec it should persist untill the user removes it on all browsers, I have not found any that have deleted on any off my projects.

A good article to read is also http://ejohn.org/blog/dom-storage/

What is the max size of localStorage values?

Quoting from the Wikipedia article on Web Storage:

Web storage can be viewed simplistically as an improvement on cookies, providing much greater storage capacity (10 MB per origin in Google Chrome(https://plus.google.com/u/0/+FrancoisBeaufort/posts/S5Q9HqDB8bh), Mozilla Firefox, and Opera; 10 MB per storage area in Internet Explorer) and better programmatic interfaces.

And also quoting from a John Resig article [posted January 2007]:

Storage Space

It is implied that, with DOM Storage,
you have considerably more storage
space than the typical user agent
limitations imposed upon Cookies.
However, the amount that is provided
is not defined in the specification,
nor is it meaningfully broadcast by
the user agent.

If you look at the Mozilla source code
we can see that 5120KB is the default
storage size for an entire domain.
This gives you considerably more space
to work with than a typical 2KB
cookie.

However, the size of this storage area
can be customized by the user
(so a
5MB storage area is not guaranteed,
nor is it implied) and the user agent
(Opera, for example, may only provide
3MB - but only time will tell.)

Calculating usage of localStorage space

I didn't find a universal way to get the remaining limit on the browsers I needed, but I did find out that when you do reach the limit there is an error message that pops up. This is of-course different in each browser.

To max it out I used this little script:

for (var i = 0, data = "m"; i < 40; i++) {
try {
localStorage.setItem("DATA", data);
data = data + data;
} catch(e) {
var storageSize = Math.round(JSON.stringify(localStorage).length / 1024);
console.log("LIMIT REACHED: (" + i + ") " + storageSize + "K");
console.log(e);
break;
}
}
localStorage.removeItem("DATA");

From that I got this information:

Google Chrome

  • DOMException:

    • code: 22
    • message: "Failed to execute 'setItem' on 'Storage': Setting the value of 'data' exceeded the quota."
    • name: "QuotaExceededError"

Mozilla Firefox

  • DOMException:

    • code: 1014
    • message: "Persistent storage maximum size reached"
    • name: "NS_ERROR_DOM_QUOTA_REACHED"

Safari

  • DOMException:

    • code: 22
    • message: "QuotaExceededError: DOM Exception 22"
    • name: "QuotaExceededError"

Internet Explorer, Edge (community)

  • DOMException:

    • code: 22
    • message: "QuotaExceededError"
    • name: "QuotaExceededError"

My solution

So far my solution is to add an extra call each time the user would save anything. And if the exception is caught then I would tell them that they are running out of storage capacity.


Edit: Delete the added data

I forgot to mention that for this to actually work you would need to delete the DATA item that was set originally. The change is reflected above by using the removeItem() function.

How to fill JavaScript localStorage to its max capacity quickly?

Thanks to @Daniel H answer which gave me an idea of how to fill localStorage quickly. Finally I came to this solution:

try{
var i;
for (i = 1 ; i <= 10000; i ++) {
localStorage.setItem('test', new Array(i * 100000).join('a'));
}
}catch(error){
console.log("test stopped at i: " + i);
try{
var j;
for (j = 1 ; j <= 100; j++) {
localStorage.setItem('test2', new Array(j * 1000).join('a'));
}
}catch(error){
console.log("test2 stopped at j: " + j);
try{
var k;
for (k = 1 ; k <= 1000; k++) {
localStorage.setItem('test3', new Array(k).join('a'));
}
}catch(error){
console.log("test3 stopped at k: " + k);
console.log("total storage: " + (i * 100000 + j * 1000 + k));
}
}
}

At first I fill localStorage in chunks of 100000 characters and I store it as "test" in localStorage. After I get exceeded the quota exception, I fill localStorage in chunks of 1000 characters until I get exceeded the quota exception again. Finally I fill localStorage character by character until I get the exception for the third time.

Now localStorage is completely full and we can test it with adding 1 more character to it like this:

localStorage.setItem("a","a")

Which throws exceeded the quota exception.

P.S: I am sure this code can be much more optimized. Any optimization is highly appreciated.

localStorage, limits and data expiration when limits are reached

Here is a small proof of concept I just whipped up. It assumes an exception is thrown when you try to store items and have no space.

Code is annotated

var Storage = function (iden) { // a storage wrapper object
var storage; // temp storage with variable
if (localStorage[iden]) { // if we already did this, reuse
storage = JSON.parse(localStorage[iden]);
} else {
// the queue is for the item order to find out oldest
storage = {
__queue: [],
items: {}
};
}

function fetch(key) {
console.log(storage);
return storage.items[key];
}

function put(key, value) {
try {
storage.__queue.push(key);
storage.items[key] = value;
localStorage[iden] = JSON.stringify(storage);
} catch (e) { // out of space
if (storage.__queue.length === 0) throw Exception("Too big anyway");
var k = storage.__queue.pop();
delete storage.items[k];
return put(key, value); //try again after deleting
}
}
return {
put: put,
fetch: fetch
};
};

What happens when LocalStorage hits the maximum storage limit for a domain?

Stating the Spec:

If it couldn't set the new value, the method must throw an
QuotaExceededError exception. (Setting could fail if, e.g., the user
has disabled storage for the site, or if the quota has been exceeded.)

So theoretically you should always use a try-catch clause to prevent that error.

for (var i = 0;i<200000;i++){
test += "sdfghyxcvbn123kjhajsdfkhuwehfkjs,dnfhkweufhkjsdf";
}
try{
var result = window.localStorage.setItem("test",test);
} catch(e) {
console.log(e.message);
}

Example Data of localstorage and sessionstorage

1) The data you store either with LocalStorage or SessionStorage depends on how you want your user to experience your application.

For example, if you have a login page, the username should be something kept with LocalStorage, because probably this same user will log into your app multiple times and not necesseraly wants to save the password in the browser. Having the username in LocalStorage will make it easier for the user to login in the future, even after closing the browser or changing tabs.

But, if you have a system that provides services like booking, searching or maybe comparison between products, storing data with SessionStorage would be better, because although the values set by the user while using your application won't change during this session, they might - and probably will - change in a future use of your application.

In your case specifically, and repeating what was said in the beginning, even with changes in your list of countries, you need to have in mind how your user will interact with your system and what are your needs with the data that is being provided by them.

Don't forget you can always clean the localStorage if you need, and set new values as they appear.

2) There's a really good explanation of how the browser responds to a full memory here



Related Topics



Leave a reply



Submit