8

I'd like to use IndexedDB to process a lot of data. Too much data to fit in memory. To do this, I would like to use Firefox's IndexedDB persistent storage, which allows me to store more than 2GB worth of data (Firefox apparently has a limit of 2GB imposed on non-persistent storage).

However, I've run into an issue. Firefox does not appear to be imposing a limit on the amount of data I can store in persistent storage. In fact, if I leave the following sample running, it will apparently run until the disk is full!

Sample (Online) (Must be run in Firefox!):

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Firefox IndexedDB Limit Test</title>
    </head>
    <body>
        <script>
(function() {
'use strict';

var IDBReq = indexedDB.open('testdb', {
    version: 1,
    storage: 'persistent'
});

IDBReq.onupgradeneeded = function() {
    this.result.createObjectStore('data');
};

var logmsg;
IDBReq.onsuccess = function() {
    var DB = this.result;
    var size = 0;

    var next = function(i) {
        var data = new Uint8Array(0xFFFF);
        crypto.getRandomValues(data);

        size += data.length;
        logmsg = 'size: ' + size + 'b ' + (size / (1024 * 1024 * 1024)) + 'gb';

        var store = DB.transaction(['data'], 'readwrite').objectStore('data');
        var storeReq = store.add(data, 'data-' + i);
        storeReq.onsuccess = function() {
            next(i + 1);
        };
        storeReq.onerror = function() {
            console.log('storeReq error');
            console.log(this.error);
        };
    };
    next(1);
};
setInterval(function() {
    if (logmsg) {
        console.log(logmsg);
        logmsg = null;
    }
}, 1000);

})();
        </script>
    </body>
</html>

For obvious reasons, filling up a user's drive is not ideal. If the user does not have enough free disk space, it would be better not to try to run it at all, or at-least stop when more-than X% full.

Strangely, according to MDN, it seems like the browser should be imposing a limit on the amount of data stored:

The maximum browser storage space is dynamic — it is based on your hard drive size. The global limit is calculated as 50% of free disk space. In Firefox, an internal browser tool called the Quota Manager keeps track of how much disk space each origin is using up, and deletes data if necessary.

So if your hard drive is 500GB, then the total storage for a browser is 250GB. If this is exceeded, a process called origin eviction comes into play, deleting entire origin's worth of data until the storage amount goes under the limit again. There is no trimming effect put in place, to delete parts of origins — deleting one database of an origin could cause problems with inconsistency.

There's also another limit called group limit — this is defined as 20% of the global limit. Each origin is part of a group (group of origins). There's one group for each eTLD+1 domain.

However, my testing never threw any errors while it filled up the drive.

Now my question is, is there any way to ensure putting a lot of data into Firefox's IndexedDB persistent storage will not fill up a user's drive, and make them very, very angry?

Community
  • 1
  • 1
Alexander O'Mara
  • 52,993
  • 16
  • 139
  • 151

1 Answers1

4

Note the line in the MDN article:

Temporary data storage does not elicit any user prompts, but there are Storage limits.

It could be clearer, but it means Storage limits ONLY apply to temporary storage. So, the global limit and group limit are not in effect for persistent storage.

You can consider switching to temporary storage. But if you need persistent then you may be out of luck until Firefox implements navigator.storageQuota or navigator.storageManager, whichever is settled on.

dgrogan
  • 2,227
  • 12
  • 19
  • Aha! Found the 2gb limiter: https://github.com/mozilla/gecko-dev/blob/c90904f9bfe70fc35e84cae49f17ebe5a171915e/dom/quota/ActorsParent.cpp#L5234-L5248 Now it makes sense. – Alexander O'Mara May 05 '17 at 02:17
  • Oh, one other thing. It looks like Firefox already has an implementation of [StorageManager](https://developer.mozilla.org/en-US/docs/Web/API/StorageManager) (enabled by default in Nightly), but `estimate` calculates the maximum temporary storage, and not the persistent storage. – Alexander O'Mara May 05 '17 at 02:33