134

I am currently developing a site that will make use of HTML5's localStorage. I've read all about the size limitations for different browsers. However, I haven't seen anything on how to find out the current size of a localStorage instance. This question seems to indicate that JavaScript doesn't have a built in way of showing the size for a given variable. Does localStorage have a memory size property that I haven't seen? Is there an easy way to do this that I'm missing?

My site is meant to allow users to enter information in an 'offline' mode, so being able to give them a warning when the storage is almost full is very important.

Community
  • 1
  • 1
derivation
  • 3,746
  • 3
  • 24
  • 23
  • 1
    http://stackoverflow.com/questions/3027142/calculating-usage-of-localstorage-space – Adam Dec 08 '10 at 19:46

14 Answers14

254

Execute this snippet in JavaScript console (one line version):

var _lsTotal=0,_xLen,_x;for(_x in localStorage){ if(!localStorage.hasOwnProperty(_x)){continue;} _xLen= ((localStorage[_x].length + _x.length)* 2);_lsTotal+=_xLen; console.log(_x.substr(0,50)+" = "+ (_xLen/1024).toFixed(2)+" KB")};console.log("Total = " + (_lsTotal / 1024).toFixed(2) + " KB");


The same code in multiple lines for reading sake

var _lsTotal = 0,
    _xLen, _x;
for (_x in localStorage) {
    if (!localStorage.hasOwnProperty(_x)) {
        continue;
    }
    _xLen = ((localStorage[_x].length + _x.length) * 2);
    _lsTotal += _xLen;
    console.log(_x.substr(0, 50) + " = " + (_xLen / 1024).toFixed(2) + " KB")
};
console.log("Total = " + (_lsTotal / 1024).toFixed(2) + " KB");

or add this text in the field 'location' of a bookmark for convenient usage

javascript: var x, xLen, log=[],total=0;for (x in localStorage){if(!localStorage.hasOwnProperty(x)){continue;} xLen =  ((localStorage[x].length * 2 + x.length * 2)/1024); log.push(x.substr(0,30) + " = " +  xLen.toFixed(2) + " KB"); total+= xLen}; if (total > 1024){log.unshift("Total = " + (total/1024).toFixed(2)+ " MB");}else{log.unshift("Total = " + total.toFixed(2)+ " KB");}; alert(log.join("\n")); 

P.S. Snippets are updated according to request in the comment. Now the calculation includes the length of the key itself. Each length is multiplied by 2 because the char in javascript stores as UTF-16 (occupies 2 bytes)

P.P.S. Should work both in Chrome and Firefox.

Serge Seletskyy
  • 13,566
  • 6
  • 59
  • 76
  • 8
    Paste this in console to see the total: var t = 0; for(var x in localStorage){ t += (((localStorage[x].length * 2))); } console.log(t/1024+ " KB"); – Henry Apr 02 '14 at 03:50
  • @Serge, I prefer KB so I just removed the last '/1024' and changed it to "kb" :) – blockloop Jun 04 '14 at 16:25
  • Why multiply the length by 2? It seems that doubles the results in MB? – Micah Jun 02 '15 at 17:48
  • @Micah, it's a good question. Unfortunately I am not able to recall why I used *2 in the formula two years ago. I guess quick googling will help you to find the answer. – Serge Seletskyy Jun 04 '15 at 13:37
  • 5
    @Micah Javascript uses UTF16 internally, so because each character is stored as two bytes you need to multiply the number of characters by two to get the actual space used. (You have probably already discovered this, but I thought it worth noting here just for anyone else has the same question) – Rebecka Jul 27 '15 at 21:39
  • A slightly changed version of this would end with a total: ```var total = 0;for(var x in localStorage) { var size = ((localStorage[x].length * 2)/1024/1024); total += size; console.log(x+"="+size.toFixed(2)+" MB")} console.log("total="+total.toFixed(2)+" MB");``` – Jpunt Aug 18 '15 at 11:29
  • What about the size of keys? I think the keys also occupy space in storage. – Mihir Nov 06 '15 at 08:30
  • Good catch @Mihir. And what do you think how to solve that issue? – Serge Seletskyy Nov 09 '15 at 12:19
  • @Serge, probably the same way it is done for values. I would then verify the result with the size in IE's 5MB - remainingSpace property. What do you think? – Mihir Nov 10 '15 at 14:55
  • 2
    @Serge, this answer is most voted hence posting here `var t = 0; for(var x in localStorage) { t += (x.length + localStorage[x].length) * 2; } console.log(t/1024+ " KB");` – Mihir Nov 17 '15 at 06:45
  • @SergeSeletskyy i think **key** is also going to occupy some space. You have just calculate the length of value form localStorage. is it true? – Dipak Prajapati Jul 28 '16 at 05:48
  • I suggest you to create a Gist. Very helpful answer. – Hitmands Aug 24 '16 at 08:39
  • 19
    Here's a modified version that accounts for NaN as well: `var _lsTotal = 0, _xLen, _x; for (_x in localStorage) { _xLen = (((localStorage[_x].length || 0) + (_x.length || 0)) * 2); _lsTotal += _xLen; console.log(_x.substr(0, 50) + " = " + (_xLen / 1024).toFixed(2) + " KB") }; console.log("Total = " + (_lsTotal / 1024).toFixed(2) + " KB");` – Mario S Sep 19 '17 at 14:25
  • 1
    There's a bug in the bookmarklet. You're using underscored variables in the main code and normal names in bookmarklet. Single underscored `_x` breaks it. Simply remove the underscore. – Soul Reaver Mar 19 '19 at 13:52
  • How does one " add the text in the field 'location' of a bookmark for convenient usage" ? – JBdev May 28 '19 at 14:10
50

Going off of what @Shourav said above, I wrote a small function that should accurately grab all your the localStorage keys (for the current domain) and calculate the combined size so that you know exactly how much memory is taken up by your localStorage object:

var localStorageSpace = function(){
        var allStrings = '';
        for(var key in window.localStorage){
            if(window.localStorage.hasOwnProperty(key)){
                allStrings += window.localStorage[key];
            }
        }
        return allStrings ? 3 + ((allStrings.length*16)/(8*1024)) + ' KB' : 'Empty (0 KB)';
    };

Mine returned: "30.896484375 KB"

tennisgent
  • 13,875
  • 9
  • 46
  • 47
18

IE has a remainingSpace property of the Storage object. The other browsers have no equivilant at this time.

I believe that the default amount of space is 5MB, although I have not tested it personally.

Adam
  • 39,529
  • 15
  • 101
  • 139
15

You can get the current size of the local storage data using the Blob function. This may not work in old browsers, check the support for new Blob and Object.values() at caniuse.

Example:

return new Blob(Object.values(localStorage)).size;

Object.values() turns the localStorage object to an array. Blob turns the array into raw data.

zb226
  • 7,475
  • 4
  • 37
  • 64
P Roitto
  • 798
  • 7
  • 7
  • 3
    I think `Blob` does not restrict string encoding to UTF-16, so this might actually be the most reliable method. `new Blob(['X']).size;` = 1 whereas `new Blob(['☃']).size` (U+2603 / snowman character) ==> 3. Solutions based on `String.prototype.length` don't take this into account (deal with "characters") whereas storage quotas/limits likely do (deal with bytes), and I could imagine this leading to surprises, for example, when storing non-English/ASCII characters. – jacobq Oct 31 '19 at 20:23
  • I used Jed's answer which calculates localStorage size with strings length to test Blob solution in Chrome & FF. In first test, I filled localStorage with sign '1'. in second test, I filled localStorage with sign ''☃'' which has larger size in Blob object. In both cases I got exactly the same maximum localStorage length. So Blob size of characters does not affect localStorage limitation. That's why Blob should not be used for this purpose. – Vincente Jun 22 '20 at 16:21
  • I get 195... 195 what? – SeanMC May 06 '21 at 20:01
  • 1
    195 bytes. https://developer.mozilla.org/en-US/docs/Web/API/Blob/size – P Roitto May 07 '21 at 06:20
14

Here is a simple example of how to do this and should work with every browser

alert(1024 * 1024 * 5 - unescape(encodeURIComponent(JSON.stringify(localStorage))).length);
jas-
  • 1,724
  • 1
  • 17
  • 28
  • don't you need a *8 somewhere in there? – George Mauer Sep 23 '14 at 20:57
  • 1
    Depends on the character set (i.e. utf8, etc) which that doesn't account for – jas- Sep 24 '14 at 11:18
  • Does this give the size in bytes, or in bits? – JamesTheAwesomeDude Nov 23 '15 at 14:58
  • 6
    This example incorrectly assumes that localStorage has the same fixed limit in 5MB (5 * 1024 * 1024) in each browser. – Victor Dec 03 '15 at 12:04
  • That is according to the spec put forth by the w3c. – jas- Dec 03 '15 at 17:02
  • @JamesTheAwesomeDude The size is in bytes. – Davuz Dec 04 '15 at 08:59
  • It's incorrect to calculate localStorage size in this way, as I mentioned here https://stackoverflow.com/questions/4391575/how-to-find-the-size-of-localstorage#comment110563581_52254155 Encoded sign size does not affect localStorage limitation. `unescape(encodeURIComponent('1')).length === 1` and `unescape(encodeURIComponent('☃').length === 3`, but the same number of these signs can be stored in localStorage until it overflows. – Vincente Jun 22 '20 at 16:47
13

Hope this help someone.

Because Jas- example on jsfiddle does not work for me I came up with this solution. (thanks to Serge Seletskyy and Shourav for their bits I used in the code below)

Below is the function that can be used to test how much space is available for localStorage and (if any keys are already in lS) how much space is left.

It is a little brute force but it works in almost every browser... apart from Firefox. Well in desktop FF it takes ages (4-5min) to complete, and on Android it just crashes.

Underneath the function is a short summary of tests that I have done in different browsers on different platforms. Enjoy!

function testLocalStorage() {
    var timeStart = Date.now();
    var timeEnd, countKey, countValue, amountLeft, itemLength;
    var occupied = leftCount = 3; //Shurav's comment on initial overhead
//create localStorage entries until localStorage is totally filled and browser issues a warning.
    var i = 0;
    while (!error) {
        try {
//length of the 'value' was picked to be a compromise between speed and accuracy, 
// the longer the 'value' the quicker script and result less accurate. This one is around 2Kb 
            localStorage.setItem('testKey' + i, '11111111112222222222333333333344444444445555555555666661111111111222222222233333333334444444444555555555566666');
        } catch (e) {
            var error = e;
        }
        i++;
    }
//if the warning was issued - localStorage is full.
    if (error) {
//iterate through all keys and values to count their length
        for (var i = 0; i < localStorage.length; i++) {
            countKey = localStorage.key(i);
            countValue = localStorage.getItem(localStorage.key(i));
            itemLength = countKey.length + countValue.length;
//if the key is one of our 'test' keys count it separately
            if (countKey.indexOf("testKey") !== -1) {
                leftCount = leftCount + itemLength;
            }
//count all keys and their values
            occupied = occupied + itemLength;
        }
        ;
//all keys + values lenght recalculated to Mb
        occupied = (((occupied * 16) / (8 * 1024)) / 1024).toFixed(2);
//if there are any other keys then our 'testKeys' it will show how much localStorage is left
        amountLeft = occupied - (((leftCount * 16) / (8 * 1024)) / 1024).toFixed(2);
//iterate through all localStorage keys and remove 'testKeys'
        Object.keys(localStorage).forEach(function(key) {
            if (key.indexOf("testKey") !== -1) {
                localStorage.removeItem(key);
            }
        });

    }
//calculate execution time
    var timeEnd = Date.now();
    var time = timeEnd - timeStart;
//create message
    var message = 'Finished in: ' + time + 'ms \n total localStorage: ' + occupied + 'Mb \n localStorage left: ' + amountLeft + "Mb";
//put the message on the screen
    document.getElementById('scene').innerText = message; //this works with Chrome,Safari, Opera, IE
//document.getElementById('scene').textContent = message;  //Required for Firefox to show messages
}

And as promised above some test in different browsers:

GalaxyTab 10.1

  • Maxthon Pad 1.7 ~1130ms 5Mb
  • Firefox 20.0(Beta 20.0) crashed both
  • Chrome 25.0.1364.169 ~22250ms /5Mb
  • Native (identifies as Safari 4.0/Webkit534.30) ~995ms /5Mb

iPhone 4s iOS 6.1.3

  • Safari ~ 520ms /5Mb
  • As HomeApp ~525ms / 5Mb
  • iCab ~ 710ms /5mb

MacBook Pro OSX 1.8.3 (Core 2 Duo 2.66 8Gb memory)

  • Safari 6.0.3 ~105ms /5Mb
  • Chrome 26.0.1410.43 ~3400ms /5Mb
  • Firefox 20.0 300150ms(!) /10Mb (after complaining about script running to long)

iPad 3 iOS 6.1.3

  • Safari ~430ms /5Mb
  • iCab ~595ms /5mb

Windows 7 -64b (Core 2 Duo 2.93 6Gb memory)

  • Safari 5.1.7 ~80ms /5Mb
  • Chrome 26.0.1410.43 ~1220ms /5Mb
  • Firefox 20.0 228500ms(!) /10Mb (after complaining about script running to long)
  • IE9 ~17900ms /9.54Mb ( if any console.logs are in the code does not work until DevTools are opened)
  • Opera 12.15 ~4212ms /3.55Mb (this is when 5Mb is selected, but Opera asks nicely if we want increase the amount of lS, unfortunately it crashes if test conducted a few times in a row)

Win 8 (Under Parallels 8)

  • IE10 ~7850ms /9.54Mb
Jakub Gadkowski
  • 161
  • 1
  • 5
  • Great experiments. However I found `array.forEach()` in your code, as I know it doesn't exist in IE, do you implement by yourself? How do you measure its contribution to the overall latency? – Evi Song Jun 27 '15 at 16:41
  • Thanks, I might to redo them since some time passed from the initial tests. As for the `forEach()`. No I have not implemented it myself, I used the stock `Array.prototype.forEach()`. According to [Mozilla Developer Network aka MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) from IE9 it has native support. – Jakub Gadkowski Jun 30 '15 at 11:20
  • Thanks. My knowledge need to be refreshed. Later I'll use `Array.prototype.forEach()` as much as possible if my project won't support early IE versions. – Evi Song Jul 03 '15 at 03:44
  • Code could be made *significantly faster* (~2500ms in Firefox, ~700ms in Chrome): split `while` loop into two parts, first one like in http://stackoverflow.com/a/3027249/1235394 that fills localStorage with exponentially growing data chunks, then second part with fixed-size small chunks to fill storage completely. Test page: http://jsfiddle.net/pqpps3tk/1/ – Victor Dec 03 '15 at 12:45
  • IE10 Rocks.. Still, the fastest browser to download Chrome :) – Ruslan Abuzant Apr 19 '16 at 14:33
7

You can calculate your localstorage by following methods:

function sizeofAllStorage(){  // provide the size in bytes of the data currently stored
  var size = 0;
  for (i=0; i<=localStorage.length-1; i++)  
  {  
  key = localStorage.key(i);  
  size += lengthInUtf8Bytes(localStorage.getItem(key));
  }  
  return size;
}

function lengthInUtf8Bytes(str) {
  // Matches only the 10.. bytes that are non-initial characters in a multi-byte sequence.
  var m = encodeURIComponent(str).match(/%[89ABab]/g);
  return str.length + (m ? m.length : 0);
}

console.log(sizeofAllStorage());

Finally size in bytes will be logged in browser.

Usman Faisal
  • 257
  • 2
  • 12
4

I would use the code of @tennisgen which get all and count the content, but I count the keys themselves:

var localStorageSpace = function(){
        var allStrings = '';
        for(var key in window.localStorage){
            allStrings += key;
            if(window.localStorage.hasOwnProperty(key)){
                allStrings += window.localStorage[key];
            }
        }
        return allStrings ? 3 + ((allStrings.length*16)/(8*1024)) + ' KB' : 'Empty (0 KB)';
    };
Arnaud Valensi
  • 111
  • 1
  • 3
3

The way I went about this problem is to create functions for finding out the used space and remaining space in Local Storage and then a function that calls those functions to determine the max storage space.

function getUsedSpaceOfLocalStorageInBytes() {
    // Returns the total number of used space (in Bytes) of the Local Storage
    var b = 0;
    for (var key in window.localStorage) {
        if (window.localStorage.hasOwnProperty(key)) {
            b += key.length + localStorage.getItem(key).length;
        }
    }
    return b;
}

function getUnusedSpaceOfLocalStorageInBytes() {
    var maxByteSize = 10485760; // 10MB
    var minByteSize = 0;
    var tryByteSize = 0;
    var testQuotaKey = 'testQuota';
    var timeout = 20000;
    var startTime = new Date().getTime();
    var unusedSpace = 0;
    do {
        runtime = new Date().getTime() - startTime;
        try {
            tryByteSize = Math.floor((maxByteSize + minByteSize) / 2);
            localStorage.setItem(testQuotaKey, new Array(tryByteSize).join('1'));
            minByteSize = tryByteSize;
        } catch (e) {
            maxByteSize = tryByteSize - 1;
        }
    } while ((maxByteSize - minByteSize > 1) && runtime < timeout);

    localStorage.removeItem(testQuotaKey);

    if (runtime >= timeout) {
        console.log("Unused space calculation may be off due to timeout.");
    }

    // Compensate for the byte size of the key that was used, then subtract 1 byte because the last value of the tryByteSize threw the exception
    unusedSpace = tryByteSize + testQuotaKey.length - 1;
    return unusedSpace;
}

function getLocalStorageQuotaInBytes() {
    // Returns the total Bytes of Local Storage Space that the browser supports
    var unused = getUnusedSpaceOfLocalStorageInBytes();
    var used = getUsedSpaceOfLocalStorageInBytes();
    var quota = unused + used;
    return quota;
}
Jed
  • 9,963
  • 17
  • 75
  • 121
  • Array.join is a performance killer, better use String.repeat where available (that means everywhere except IE) – pkExec Feb 01 '17 at 11:06
2

In addition to @serge's answer which is most voted here, size of the keys need to be considered. Code below will add the size of the keys stored in localStorage

var t = 0; 
for (var x in localStorage) { 
    t += (x.length + localStorage[x].length) * 2; 
} 
console.log((t / 1024) + " KB");
Mihir
  • 309
  • 2
  • 9
  • I've found that Firefox returns `undefined` for the item `length` in some cases, so I've added a conditional to the addition: `t += (x.length + (this.storage[x].length ? this.storage[x].length : 0)) * 2;`. – camilokawerin Nov 26 '15 at 23:07
  • @camilokawerin, it shouldn't unless an undefined value is saved in the storage, because String is the only type which is supported with localStorage and String does have property Length. Could you post some example on jsfiddle or something similar? – Mihir Nov 27 '15 at 16:28
1

As the spec goes, each character of a string is 16 bit.

But inspecting with chrome (Settings>Content Settings>Cookies & Site data) shows us that initiating localStorage takes 3kB (overhead size)

And stored data size follows this relation (accurate to 1kB)
3 + ((localStorage.x.length*16)/(8*1024)) kB

where localStorage.x is your storage string.

ShouravBR
  • 515
  • 5
  • 9
0

//Memory occupy by both key and value so Updated Code.

var jsonarr=[];
var jobj=null;
for(x in sessionStorage) // Iterate through each session key
{
    jobj={}; 
    jobj[x]=sessionStorage.getItem(x); //because key will also occupy some memory
    jsonarr.push(jobj);
    jobj=null;
}
//https://developer.mozilla.org/en/docs/Web/JavaScript/Data_structures 
//JavaScript's String type is used to represent textual data. It is a set of "elements" of 16-bit unsigned integer values. 
var size=JSON.stringify(jsonarr).length*2; //16-bit that's why multiply by 2
var arr=["bytes","KB","MB","GB","TB"]; // Define Units
var sizeUnit=0;
while(size>1024){ // To get result in Proper Unit
    sizeUnit++;
    size/=1024;
}
alert(size.toFixed(2)+" "+arr[sizeUnit]);
Dipak Prajapati
  • 404
  • 3
  • 11
0

Yes, this question was asked like 10 years ago. But for those interested (like myself, as I am building an offline text editor that saves data with local storage) and suck at programming, you could use something simple like this:

var warning = 1;
var limit = 2000000; //2 million characters, not really taking in account to bytes but for tested ammounts of characters stored
setInterval(function() {
    localStorage["text"] = document.getElementById("editor").innerHTML; //gets text and saves it in local storage under "text"
    if(localStorage["text"].length > limit && warning == 1){
            alert("Local Storage capacity has been filled"); 
            warning = 2; //prevent a stream of alerts
    }
}, 1000);
//setInterval function saves and checks local storage

The best way to get the amount of storage filled is to view the site settings (say, if you stored an image in local storage). At least in chrome, you can see the amount of bytes used (ie: 1222 bytes). However, the best ways to see filled local storage with js have already been mentioned above, so use them.

Nathan Su
  • 1
  • 3
-1
window.localStorage.remainingSpace
Pradeep Singh
  • 3,424
  • 3
  • 26
  • 41