This specification defines an API to manage usage and availability of local storage resources, and defines a means by which a user agent (UA) may grant Web applications permission to use more local space, temporarily or persistently, via various different storage APIs.

Introduction

Today we have a variety of storage APIs that can store inherently complex or large data in order to satisfy offline data requirements of Web applications. Examples of these APIs include: Application Cache [[OFFLINE-WEBAPPS]], File API: Directories and System (File System API) [[FILE-SYSTEM]], Indexed Database [[INDEXEDDB]] and Web SQL Database [[WEBSQL]].

These APIs may require larger local space than the conventional cookie storage or Web Storage [[WEBSTORAGE]], but they do not provide a means by which a Web application can query and manage how much data is currently stored and how much more can be stored.

This specification defines an API to query and manage usage and availability of a user's local storage. The storage space granted by the API is intended to be shared by different storage APIs, therefore a user and UA only need to manage single upper limit for all storage per logical application unit, e.g. per origin or per browser (which is implementation specific).

Storage Types

Temporary vs Persistent

A Web application can request temporary or persistent local storage space depending on its purpose.

Temporary type of storage is especially useful if an application wants to cache data locally to improve its performance, but can fall back to fetching or recreating the same data at a data loss.

Conversely, persistent type of storage is useful if an application wants to store critical offline data that is necessary to be functional, or wants to manage local data amount and lifetime on its own policy rather than relying on the UA's default eviction policy for temporary storage.

Examples

Suppose there is a photo editing application. This application manages user photo data using Indexed Database [[INDEXEDDB]], stores photo images using Filesystem API [[FILE-SYSTEM]] and optinally utilizes Application Cache [[OFFLINE-WEBAPPS]] to make it work offline.

The application needs to query how much data it can store in the temporary storage to determine its initial cache size.

          // Query current usage and availability in Temporary storage:
          navigator.storageInfo.queryUsageAndQuota(
            "temporary",
            function (usage, quota) {
              // Continue to initialize local cache using the obtained
              // usage and quota (availability) information.
              initializeCache(usage, quota);
            },
            function (error) { log("Got error: ", error); });
          

Similarly, the application needs to request additional persistent storage to support offline mode when it is enabled by the user.

          function onError(error) {
            // Handle an error.
            log("Got error: ", error);
          }

          function setUpOfflineMode(availableSpace) {
            // ...
          }

          // A function which is to be called when 'offline-mode' is enabled.
          function onOfflineEnabled(amountOfSpaceNeeded) {
            // First check how much we can use in the Persistent storage.
            navigator.storageInfo.queryUsageAndQuota(
              "persistent",
              function (usage, quota) {
                var availableSpace = quota - usage;
                if (availableSpace >= amountOfSpaceNeeded) {
                  // We're fine; just continue to set up offline mode.
                  setUpOfflineMode(availableSpace);
                  return;
                }
                var requestingQuota = amountOfSpaceNeeded + usage;
                navigator.storageInfo.requestQuota(
                    "persistent",
                    requestingQuota,
                    function (grantedQuota) {
                      setUpOfflineMode(grantedQuota - usage);
                    },
                    onError);
              },
              onError);
          }
        

Quota Management API

StorageType enum

The string enum is used to indicate temporary or persistent storage type.
{ "temporary", "persistent" }
Used to indicate the storage type.

StorageInfo interface

The StorageInfo interface provides means to query and request storage usage and quota information. The API provided by the interface is asynchronous since querying or allocating space in a user's local storage may require blocking I/O operations, e.g. examining the local disk status or making changes in a local database.

void queryUsageAndQuota(StorageType type, optional StorageInfoUsageCallback successCallback, optional StorageInfoErrorCallback errorCallback)
Queries the current usage (how much data is stored) and quota available for the requesting application. Either one of successCallback or errorCallback is called to indicate the request is successfully handled or not.
void requestQuota(StorageType type, unsigned long long newQuotaInBytes, optional StorageInfoQuotaCallback successCallback, optional StorageInfoErrorCallback errorCallback)
Requests a new quota for the requesting application. It is not guaranteed that the requested amount of space is granted just by calling this API. Calling this API MAY trigger user prompting to request explicit user permission to proceed. Either one of successCallback or errorCallback is called to indicate the request is successfully handled or not. successCallback MAY return a smaller amount of quota than requested.

This interface is defined after the storage model defined in File System API [[FILE-SYSTEM]], and therefore uses the terminology and interface model similar to the API, e.g. employing Callback model rather than Event model.

Restrictions

The space queried and granted by StorageInfo MUST have the following properties:

  • The space granted for persistent type SHOULD NOT be deleted by the UA, other than in a response to a removal API call, without explicit authorization from the user.
  • The space granted for temporary type MAY be deleted by the UA at its discretion, without application or user intervention due to local resource shortage or for other reasons.
  • When the UA deletes the data in temporary storage, the UA SHOULD avoid partial or incomplete deletion which could leave the application in an unrecoverable inconsistent state.

StorageInfoUsageCallback callback

This callback is used to return usage and quota information.

void (unsigned long long currentUsageInBytes, unsigned long long currentQuotaInBytes)

Used to supply the current usage and quota information in bytes.

currentUsageInBytes indicates the total amount of data stored in the storage of the requested storage type. Depending on the UA's usage tracking system the returned value MAY differ from the exact real-time usage of the user's physical local storage.

currentQuotaInBytes indicates the current upper limit of the storage space that is exposed to and can be used by the requesting application.

StorageInfoQuotaCallback callback

This callback is used to return a new quota information granted by a UA.

void (unsigned long long grantedQuotaInBytes)

StorageInfoErrorCallback callback

This interface is the callback used to indicate an error has occured.

void (DOMError error)
There was an error with the request. Details are provided by the error parameter.

Accessing StorageInfo

All instances of Navigator type are defined to also implement QuotaStorageEnvironment interface.

readonly attribute StorageInfo storageInfo
This attribute provides applications a means to access Quota Management API.

Quota handling in storage API

Storage APIs except for Web Storage, i.e. Application Cache, File System API, Indexed Database and Web SQL Database, SHOULD respect the quota management API and MUST have following properties:

Acknowledgements

Many thanks to Robin Berjon for making our lives so much easier with his cool tool.