What is the max size of localStorage values?
Asked Answered
J

13

707

Since localStorage (currently) only supports strings as values, and in order to do that the objects need to be stringified (stored as JSON-string) before they can be stored, is there a defined limitation regarding the length of the values.

Does anyone know if there is a definition which applies to all browsers?

Jessiejessika answered 7/6, 2010 at 12:9 Comment(5)
I think no one actually answered the "max length per value" question.Resilience
@PeteAlvin I just answered the question.Raymer
All browsers: html5rocks.com/en/tutorials/offline/quota-researchHump
@PeteAlvin Somebody answered it in 2015. The other answers address the limit on the total size, but not the limit on the size per value.Starlastarlene
I made this Code Sandbox to find out what was my limit (5MB), if anyone is interested : codesandbox.io/s/localstorage-capacity-cillxb?file=/src/…Rhapsodic
R
509

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.)

Rendition answered 7/6, 2010 at 12:12 Comment(11)
I didn't understand the per origin bit? If a website foo.com has 200 users, will it be 5 MB for all of those 200 users surfing that page?Educative
@Cupidvogel no, it means each domain (origin) can store 5MB on any individual client. The data is stored on the clients machine - in no way does the localStorage mechanism interact across clients.Startling
Just a dumb question, by domain you really mean domain, right? So foo.com and foo.com/boo.html will both point to the same domain and the localstorage usage will be the combined one for both these pages for the domain foo.com, right?Educative
No, I just wanted to ensure that the same data is accessible across multiple pages for the same domain. Often I find the phrases domain and page spelled out synonymously, so just wanted to know for sure!Educative
@Cupidvogel, yes foo.com and foo.com/bar.html would use the same localstorage but foo.com and bar.com OR foo.com and bar.foo.com would have different localstorage. Of course as @Startling said, this is per-user as it is stored on the clients computer. So you can have XMB for user A and XMB for user B where X is the number of MB each browser will allow you. Does that answer your question?Avelinaaveline
Is there, however, a limitation on a single value ? (If I have a lot of flags to store, how safe is it to store it as JSON in a single property ?)Sperling
I've got Safari at 5MB and Chrome 39 at 10MB (not sure when it was boosted from 5MB) See this article html5rocks.com/en/tutorials/offline/quota-researchPantia
@Cupidvogel: No, it's not by domain, it's by origin, as the term is used vis-a-vis the Same Origin Policy and such: scheme+host+port. http://example.com and https://example.com are not the same origin (different schemes). http://example.com and http://www.example.com are not the same origin (different hosts). http://example.com and http://example.com:8080 are not the same origin (different ports). HTH. :-)Festoonery
Chrome has increase the limit to 10 MB per origin (plus.google.com/u/0/+FrancoisBeaufort/posts/S5Q9HqDB8bh) I tested it on arty.name/localstorage.html and got a 10M https_arty.name_0.localstorage. @PantiaFlagstone
I thought cookie size was 4.1 MB?Lat
Just to highlight to everyone, that this means if 2 users use the same browser on the same machine, they will share this storage.Tum
V
165

Actually Opera doesn't have 5MB limit. It offers to increase limit as applications requires more. User can even choose "Unlimited storage" for a domain.

You can easily test localStorage limits/quota yourself.

Valeta answered 15/7, 2010 at 21:24 Comment(7)
Doesn't crash Chrome anymore... Interesting point: 5MB equals 2.5 Million chars on Chrome. So apparently, UFT16 is used for localStore.Slew
@FelixAlcala Unfortunately, it crashes Chrome 15.0.874.54 beta on Mac OS X. I had a crash at 1.500.000 chars.Mcqueen
It crashed chrome on my device, also reset the bckground, not surprised though, my phone has such little RAM, it can't handle having a stupid FLASHLIGHT APP open while chrome is open.Nightcap
@FelixAlcala -- Actually, JavaScript exposes UCS-2. While it is similar to UFT16 there are some very important differences... mostly revolving around fact that UCS-2 predates UFT.Boer
@FelixAlcala Do you think that displaying how many characters as well as its disk size equivalent (e.g. 2,700K characters ~= 5,274 KB) is a good idea?Smalls
I ran this test recently on Chrome 80 and got 5.2 million chars with the 5MB still allowedWeiser
It gives a fixed answer in all the top 4 browsers - 5200000 characters were stored successfully, but 5300000 weren't.Bullwhip
B
108

Here's a straightforward script for finding out the limit:

if (localStorage && !localStorage.getItem('size')) {
    var i = 0;
    try {
        // Test up to 10 MB
        for (i = 250; i <= 10000; i += 250) {
            localStorage.setItem('test', new Array((i * 1024) + 1).join('a'));
        }
    } catch (e) {
        localStorage.removeItem('test');
        localStorage.setItem('size', i - 250);            
    }
}

Here's the gist, JSFiddle and blog post.

The script will test setting increasingly larger strings of text until the browser throws and exception. At that point it’ll clear out the test data and set a size key in localStorage storing the size in kilobytes.

Burson answered 12/9, 2014 at 16:12 Comment(6)
Cool solution. I found this one liner, what do you think?Piperpiperaceous
@Piperpiperaceous I think that one liner assumes you have 5MB and then subtracts the amount being used.Burson
Ooook, sure shot. The issue I'm having with your code is not being able to get correct results with Correct way to convert size in bytes to KB, MB, GB in Javascript... I'll revise this tomorrow but if you can take a look, appreciated.Piperpiperaceous
improved the performance and the quality of this answer hereMetheglin
It's 2020 and this answer works perfectly fine on both vanilla Chrome and Firefox on Win10, giving size=5000.Spinner
Nice solution, however i reversed the loop as I think you have less cycles, when you loop down from 10k instead increasing the number. You can use break,when no error occurs.Winifred
R
46

Find the maximum length of a single string that can be stored in localStorage

This snippet will find the maximum length of a String that can be stored in localStorage per domain.

//Clear localStorage
for (var item in localStorage) delete localStorage[item];

window.result = window.result || document.getElementById('result');

result.textContent = 'Test running…';

//Start test
//Defer running so DOM can be updated with "test running" message
setTimeout(function () {

    //Variables
    var low = 0,
        high = 2e9,
        half;

    //Two billion may be a little low as a starting point, so increase if necessary
    while (canStore(high)) high *= 2;


    //Keep refining until low and high are equal
    while (low !== high) {
        half = Math.floor((high - low) / 2 + low);

        //Check if we can't scale down any further
        if (low === half || high === half) {
            console.info(low, high, half);
            //Set low to the maximum possible amount that can be stored 
            low = canStore(high) ? high : low;
            high = low;
            break;
        }


        //Check if the maximum storage is no higher than half
        if (storageMaxBetween(low, half)) {
            high = half;
            //The only other possibility is that it's higher than half but not higher than "high"
        } else {
            low = half + 1;
        }

    }

    //Show the result we found!
    result.innerHTML = 'The maximum length of a string that can be stored in localStorage is <strong>' + low + '</strong> characters.';

    //Functions
    function canStore(strLen) {
        try {
            delete localStorage.foo;
            localStorage.foo = Array(strLen + 1).join('A');
            return true;
        } catch (ex) {
            return false;
        }
    }


    function storageMaxBetween(low, high) {
        return canStore(low) && !canStore(high);
    }

}, 0);
<h1>LocalStorage single value max length test</h1>

<div id='result'>Please enable JavaScript</div>

Note that the length of a string is limited in JavaScript; if you want to view the maximum amount of data that can be stored in localStorage when not limited to a single string, you can use the code in this answer.

Edit: Stack Snippets don't support localStorage, so here is a link to JSFiddle.

Results

Chrome (45.0.2454.101): 5242878 characters
Firefox (40.0.1): 5242883 characters
Internet Explorer (11.0.9600.18036): 16386 122066 122070 characters

I get different results on each run in Internet Explorer.

Raymer answered 12/10, 2015 at 15:38 Comment(1)
Funny, but your simple test halt my pretty powerful system when I test in Edge browser (on Win 10) after ~1 minutes run. So I can't append new data to your results ))Gobi
C
29

Don't assume 5MB is available - localStorage capacity varies by browser, with 2.5MB, 5MB and unlimited being the most common values. Source: http://dev-test.nemikor.com/web-storage/support-test/

Concentration answered 10/2, 2012 at 6:53 Comment(0)
B
24

I wrote this simple code that is testing localStorage size in bytes.

https://github.com/gkucmierz/Test-of-localStorage-limits-quota

const check = bytes => {
  try {
    localStorage.clear();
    localStorage.setItem('a', '0'.repeat(bytes));
    localStorage.clear();
    return true;
  } catch(e) {
    localStorage.clear();
    return false;
  }
};

Github pages:

https://gkucmierz.github.io/Test-of-localStorage-limits-quota/

I have the same results on desktop Google chrome, opera, firefox, brave and mobile chrome which is ~10Mbytes

enter image description here

And half smaller result in safari ~4Mbytes

enter image description here

Burress answered 3/5, 2020 at 22:43 Comment(2)
~5 millions characters stored using "UCS-2" encoding = 10 MB, not 5 MB. JavaScript uses "UCS-2", which is similar to "UTF-16". It needs 2 bytes per characters.Wiggly
Correct, it was pointed out here github.com/gkucmierz/Test-of-localStorage-limits-quota/issues/1 and it is fixed right now.Burress
V
16

You don't want to stringify large objects into a single localStorage entry. That would be very inefficient - the whole thing would have to be parsed and re-encoded every time some slight detail changes. Also, JSON can't handle multiple cross references within an object structure and wipes out a lot of details, e.g. the constructor, non-numerical properties of arrays, what's in a sparse entry, etc.

Instead, you can use Rhaboo. It stores large objects using lots of localStorage entries so you can make small changes quickly. The restored objects are much more accurate copies of the saved ones and the API is incredibly simple. E.g.:

var store = Rhaboo.persistent('Some name');
store.write('count', store.count ? store.count+1 : 1);
store.write('somethingfancy', {
  one: ['man', 'went'],
  2: 'mow',
  went: [  2, { mow: ['a', 'meadow' ] }, {}  ]
});
store.somethingfancy.went[1].mow.write(1, 'lawn');

BTW, I wrote it.

Value answered 1/10, 2014 at 11:32 Comment(3)
Thanks Martin. You might as well check my 'evon' repo as well. It's only a serialiser right now and the ink is very wet, but it's faster than rhaboo and equally versatile. Rhaboo will soon be converted to use it internally.Value
Useful but I don't think this addresses the question "What is the max size of localStorage;" your answer could be improved by stating what happens when this library tries to store something beyond the size limit, and how to react to it.Callosity
Cool, but not an answer to the question. −1.Mephitic
Z
9

I've condensed a binary test into this function that I use:

function getStorageTotalSize(upperLimit/*in bytes*/) {
    var store = localStorage, testkey = "$_test"; // (NOTE: Test key is part of the storage!!! It should also be an even number of characters)
    var test = function (_size) { try { store.removeItem(testkey); store.setItem(testkey, new Array(_size + 1).join('0')); } catch (_ex) { return false; } return true; }
    var backup = {};
    for (var i = 0, n = store.length; i < n; ++i) backup[store.key(i)] = store.getItem(store.key(i));
    store.clear(); // (you could iterate over the items and backup first then restore later)
    var low = 0, high = 1, _upperLimit = (upperLimit || 1024 * 1024 * 1024) / 2, upperTest = true;
    while ((upperTest = test(high)) && high < _upperLimit) { low = high; high *= 2; }
    if (!upperTest) {
        var half = ~~((high - low + 1) / 2); // (~~ is a faster Math.floor())
        high -= half;
        while (half > 0) high += (half = ~~(half / 2)) * (test(high) ? 1 : -1);
        high = testkey.length + high;
    }
    if (high > _upperLimit) high = _upperLimit;
    store.removeItem(testkey);
    for (var p in backup) store.setItem(p, backup[p]);
    return high * 2; // (*2 because of Unicode storage)
}

It also backs up the contents before testing, then restores them.

How it works: It doubles the size until the limit is reached or the test fails. It then stores half the distance between low and high and subtracts/adds a half of the half each time (subtract on failure and add on success); honing into the proper value.

upperLimit is 1GB by default, and just limits how far upwards to scan exponentially before starting the binary search. I doubt this will even need to be changed, but I'm always thinking ahead. ;)

On Chrome:

> getStorageTotalSize();
> 10485762
> 10485762/2
> 5242881
> localStorage.setItem("a", new Array(5242880).join("0")) // works
> localStorage.setItem("a", new Array(5242881).join("0")) // fails ('a' takes one spot [2 bytes])

IE11, Edge, and FireFox also report the same max size (10485762 bytes).

Zelda answered 20/3, 2019 at 22:5 Comment(2)
(And don't forget to localStorage.Clear() before and after your testingHegarty
No need, this function already clears the items and restores them afterwards.Zelda
F
7

I'm doing the following:

getLocalStorageSizeLimit = function () {

    var maxLength = Math.pow(2,24);
    var preLength = 0;
    var hugeString = "0";
    var testString;
    var keyName = "testingLengthKey";

    //2^24 = 16777216 should be enough to all browsers
    testString = (new Array(Math.pow(2, 24))).join("X");

    while (maxLength !== preLength) {
        try  {
            localStorage.setItem(keyName, testString);

            preLength = testString.length;
            maxLength = Math.ceil(preLength + ((hugeString.length - preLength) / 2));

            testString = hugeString.substr(0, maxLength);
        } catch (e) {
            hugeString = testString;

            maxLength = Math.floor(testString.length - (testString.length - preLength) / 2);
            testString = hugeString.substr(0, maxLength);
        }
    }

    localStorage.removeItem(keyName);

    // Original used this.storageObject in place of localStorage.  I can only guess the goal is to check the size of the localStorage with everything but the testString given that maxLength is then added.
    maxLength = JSON.stringify(localStorage).length + maxLength + keyName.length - 2;

    return maxLength;
};
Futch answered 16/6, 2014 at 21:28 Comment(2)
Maroun Maroun: Check the post again, the author has provided code to programatically check the maximum size of the local storage. This does seem to be a valid answer, and not another question.Lightyear
Executing this codes throws an "Illegal return statement" error in Chrome, as of time of writingDependent
F
7

You can use the following code in modern browsers to efficiently check the storage quota (total & used) in real-time:

if ('storage' in navigator && 'estimate' in navigator.storage) {
        navigator.storage.estimate()
            .then(estimate => {
                console.log("Usage (in Bytes): ", estimate.usage,
                            ",  Total Quota (in Bytes): ", estimate.quota);
            });
}
Fayth answered 21/5, 2018 at 12:58 Comment(2)
Doesn't work well for Chrome. Usage (in Bytes): 647 , Total Quota (in Bytes): 32901464711 That is wrong: the total size possible is actually 10485762.Zelda
do not use it! my localStorage is absolutely full (cannot write to), but estimate says Usage (in Bytes): 22849625 , Total Quota (in Bytes): 600121223577Phloem
M
6

I really like cdmckay's answer, but it does not really look good to check the size in a real time: it is just too slow (2 seconds for me). This is the improved version, which is way faster and more exact, also with an option to choose how big the error can be (default 250,000, the smaller error is - the longer the calculation is):

function getLocalStorageMaxSize(error) {
  if (localStorage) {
    var max = 10 * 1024 * 1024,
        i = 64,
        string1024 = '',
        string = '',
        // generate a random key
        testKey = 'size-test-' + Math.random().toString(),
        minimalFound = 0,
        error = error || 25e4;

    // fill a string with 1024 symbols / bytes    
    while (i--) string1024 += 1e16;

    i = max / 1024;

    // fill a string with 'max' amount of symbols / bytes    
    while (i--) string += string1024;

    i = max;

    // binary search implementation
    while (i > 1) {
      try {
        localStorage.setItem(testKey, string.substr(0, i));
        localStorage.removeItem(testKey);

        if (minimalFound < i - error) {
          minimalFound = i;
          i = i * 1.5;
        }
        else break;
      } catch (e) {
        localStorage.removeItem(testKey);
        i = minimalFound + (i - minimalFound) / 2;
      }
    }

    return minimalFound;
  }
}

To test:

console.log(getLocalStorageMaxSize()); // takes .3s
console.log(getLocalStorageMaxSize(.1)); // takes 2s, but way more exact

This works dramatically faster for the standard error; also it can be much more exact when necessary.

Metheglin answered 14/3, 2016 at 12:39 Comment(1)
Just FYI, tried to use this function in a React app and it crashes all mobile browsers on iOS: Chrome, Safari, FF in iOS 14.6.Ailing
T
4

Once I developed Chrome (desktop browser) extension and tested Local Storage real max size for this reason.

My results:

Ubuntu 18.04.1 LTS (64-bit)
Chrome 71.0.3578.98 (Official Build) (64-bit)
Local Storage content size 10240 KB (10 MB)

More than 10240 KB usage returned me the error:

Uncaught DOMException: Failed to execute 'setItem' on 'Storage': Setting the value of 'notes' exceeded the quota.

Edit on Oct 23, 2020

For a Chrome extensions available chrome.storage API. If you declare the "storage" permission in manifest.js:

{
    "name": "My extension",
    ...
    "permissions": ["storage"],
    ...
}

You can access it like this:

chrome.storage.local.QUOTA_BYTES // 5242880 (in bytes)
Thornie answered 18/4, 2019 at 16:23 Comment(0)
P
0

According to web.dev the size is limited to almost around 5-10 MB

localStorage tested on Chrome 113.0.5672.63

itself, but the article vehemently opposes using localstorage as it is synchronous and blocks the JS thread; which is a deal breaker. Another limitation is strict string storage policy (sssp) which takes a lot of preprocessing to parse and get desired o/p.

A comparative analysis on all forms of storage for the web is mentioned here. take a look:

https://web.dev/storage-for-the-web/#:~:text=LocalStorage%20should%20be%20avoided%20because,web%20workers%20or%20service%20workers.

Piled answered 5/5, 2023 at 15:20 Comment(2)
Funny. A synchronous storage approach is exactly what I need.Tolan
@Tolan how do you justify blocking the main thread to prioritize sync. operations? could you state your use case in terms of what are you trying to achieve?Piled

© 2022 - 2024 — McMap. All rights reserved.