unlimitedStorage Permission

6 min read

unlimitedStorage Permission

What It Grants

Removes the quota limits on chrome.storage.local, IndexedDB, Cache API, and other client-side storage used by the extension. Without it, chrome.storage.local is limited to ~10 MB.

Manifest

{
  "permissions": ["unlimitedStorage"]
}

User Warning

None — this permission does not trigger a warning at install time.

What It Affects

| Storage Type | Without Permission | With Permission | |—|—|—| | chrome.storage.local | ~10 MB | Unlimited | | chrome.storage.sync | 100 KB (always) | 100 KB (unchanged) | | chrome.storage.session | ~10 MB | Unlimited | | IndexedDB | ~limited | Unlimited | | Cache API (Service Worker) | ~limited | Unlimited | | Web SQL (deprecated) | ~limited | Unlimited |

Note: chrome.storage.sync is always limited to 100 KB total / 8 KB per item regardless of this permission.

When You Need It

import { createStorage, defineSchema } from '@theluckystrike/webext-storage';

const schema = defineSchema({
  cachedArticles: 'string',     // Could be many MB of cached content
  imageData: 'string',          // Base64 encoded images
  activityLog: 'string',        // Growing log data
  offlineData: 'string'         // Offline-first app data
});
const storage = createStorage(schema, 'local');

// Without unlimitedStorage, writing >10 MB would fail
await storage.set('cachedArticles', largeJsonString);

Checking Storage Usage

How to Check unlimitedStorage Usage

// Check how much storage is in use
const bytesInUse = await chrome.storage.local.getBytesInUse(null);
console.log(`Using ${(bytesInUse / 1024 / 1024).toFixed(2)} MB`);

// Check specific keys
const keyBytes = await chrome.storage.local.getBytesInUse(['cachedArticles']);
console.log(`cachedArticles: ${(keyBytes / 1024).toFixed(0)} KB`);

Storage Management Pattern

import { createMessenger } from '@theluckystrike/webext-messaging';

type Messages = {
  GET_STORAGE_INFO: { request: {}; response: { totalMB: number; keys: Record<string, number> } };
  CLEANUP_STORAGE: { request: { maxMB: number }; response: { freedMB: number } };
};
const m = createMessenger<Messages>();

m.onMessage('GET_STORAGE_INFO', async () => {
  const total = await chrome.storage.local.getBytesInUse(null);
  const all = await chrome.storage.local.get(null);
  const keys: Record<string, number> = {};
  for (const key of Object.keys(all)) {
    keys[key] = await chrome.storage.local.getBytesInUse(key);
  }
  return { totalMB: total / (1024 * 1024), keys };
});

m.onMessage('CLEANUP_STORAGE', async ({ maxMB }) => {
  const before = await chrome.storage.local.getBytesInUse(null);
  // Remove old cached data, logs, etc.
  const all = await chrome.storage.local.get(null);
  const staleKeys = Object.keys(all).filter(k => k.startsWith('cache_'));
  if (staleKeys.length > 0) {
    await chrome.storage.local.remove(staleKeys);
  }
  const after = await chrome.storage.local.getBytesInUse(null);
  return { freedMB: (before - after) / (1024 * 1024) };
});

IndexedDB with Unlimited Storage

// IndexedDB also benefits from unlimitedStorage
const db = await new Promise<IDBDatabase>((resolve, reject) => {
  const request = indexedDB.open('myExtensionDB', 1);
  request.onupgradeneeded = (event) => {
    const db = (event.target as IDBOpenDBRequest).result;
    db.createObjectStore('files', { keyPath: 'id' });
  };
  request.onsuccess = () => resolve(request.result);
  request.onerror = () => reject(request.error);
});

// Store large files without quota errors
const tx = db.transaction('files', 'readwrite');
tx.objectStore('files').put({ id: 'large-file', data: largeBlob });

Common Use Cases

When NOT to Use

Best Practices

Permission Check

import { checkPermission } from '@theluckystrike/webext-permissions';
const granted = await checkPermission('unlimitedStorage');

Cross-References

Frequently Asked Questions

What does unlimitedStorage permission do?

The unlimitedStorage permission removes the 10MB quota for chrome.storage.local, allowing extensions to store more data.

Is unlimitedStorage required for all storage?

No, it’s optional. Without it, local storage is limited to 10MB. Most extensions don’t need unlimited storage. —

Part of the Chrome Extension Guide by theluckystrike. Built at zovo.one.

No previous article
No next article