Chrome Extension Storage Quota — Limits, Best Practices, and Data Management
6 min readChrome Extension Storage Quota — Limits, Best Practices, and Data Management
Managing storage effectively is critical for Chrome extension developers. Understanding the quota limits imposed by Chrome and implementing proper data management strategies ensures your extension remains functional and reliable across different usage scenarios.
Understanding Storage Quota Limits
Chrome provides two primary storage APIs for extensions: chrome.storage.local and chrome.storage.sync. Each has distinct quota limitations that developers must consider when designing their data storage strategy.
Local Storage Quota
The chrome.storage.local API provides the most generous storage capacity with a 10MB (approximately 10,485,760 bytes) quota per extension. This storage persists locally on the user’s machine and does not sync across devices. Local storage is ideal for storing large datasets, cached content, user preferences, and application state that doesn’t need to travel with the user across different devices.
When you approach the local storage limit, Chrome will throw a QUOTA_BYTES error when attempting to write beyond capacity. It’s essential to implement proper checks before storing large amounts of data to prevent runtime failures.
Sync Storage Quota
The chrome.storage.sync API offers 100KB (approximately 102,400 bytes) of storage that synchronizes across all devices where the user is signed into Chrome with the same account. This makes it perfect for storing user preferences, settings, and small amounts of data that should persist across devices.
Each individual item in sync storage is limited to 8KB via the QUOTA_BYTES_PER_ITEM constant. This means you cannot store a single key-value pair larger than 8KB in sync storage, though you can have many smaller items that total up to 100KB.
Summary of Storage Limits
| Storage Type | Total Quota | Per-Item Limit |
|---|---|---|
chrome.storage.local |
10 MB | Unlimited* |
chrome.storage.sync |
100 KB | 8 KB |
*While there’s no explicit per-item limit for local storage, extremely large items may impact performance.
Monitoring Storage Usage with getBytesInUse
Before storing data, especially large datasets, you should check your current storage usage using the chrome.storage.local.getBytesInUse() and chrome.storage.sync.getBytesInUse() methods. This API allows you to:
- Check total storage usage by passing no arguments
- Check usage for specific keys by passing a string or array of strings
- Make informed decisions before attempting to write data
// Check total bytes used in local storage
chrome.storage.local.getBytesInUse((bytesInUse) => {
console.log(`Using ${bytesInUse} of 10,485,760 bytes`);
});
// Check usage for specific keys
chrome.storage.local.getBytesInUse(['cachedData', 'userPreferences'], (bytesInUse) => {
console.log(`Cached data and preferences use ${bytesInUse} bytes`);
});
// Determine available space
chrome.storage.local.getBytesInUse((bytesInUse) => {
const available = 10485760 - bytesInUse;
console.log(`Available space: ${available} bytes`);
});
This proactive approach prevents QUOTA_BYTES errors and allows you to implement graceful degradation when storage approaches capacity.
Compression Strategies for Efficient Storage
When dealing with large datasets, compression significantly extends your effective storage capacity. Here are practical compression strategies:
JSON Compression
For structured data like arrays and objects, compress before storing:
import LZString from 'lz-string';
// Compress before storing
const compressData = (data) => {
const jsonString = JSON.stringify(data);
return LZString.compressToUTF16(jsonString);
};
// Decompress when reading
const decompressData = (compressed) => {
const jsonString = LZString.decompressFromUTF16(compressed);
return JSON.parse(jsonString);
};
// Usage
const largeDataset = [{ /* many items */ }];
chrome.storage.local.set({
compressedData: compressData(largeDataset)
});
Selective Storage
Instead of storing complete datasets, store only essential information:
// Instead of storing full user objects
const fullUser = {
id: 1,
name: 'John Doe',
email: 'john@example.com',
avatar: 'base64encodedimage...', // Large!
preferences: { /* many preferences */ }
};
// Store minimal data
const minimalUser = {
id: 1,
name: 'John Doe',
preferences: { theme: 'dark', notifications: true }
};
Data Pruning Techniques
Implementing intelligent data pruning ensures your extension continues functioning as storage fills. Consider these approaches:
LRU (Least Recently Used) Eviction
const MAX_ITEMS = 100;
const addItemWithEviction = async (key, value) => {
const { cache = {} } = await chrome.storage.local.get('cache');
// Add new item with timestamp
cache[key] = {
data: value,
timestamp: Date.now()
};
// Sort by timestamp and remove oldest
const entries = Object.entries(cache).sort((a, b) => b[1].timestamp - a[1].timestamp);
if (entries.length > MAX_ITEMS) {
const keepEntries = entries.slice(0, MAX_ITEMS);
const newCache = Object.fromEntries(keepEntries);
await chrome.storage.local.set({ cache: newCache });
} else {
await chrome.storage.local.set({ cache });
}
};
Time-Based Cleanup
const MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000; // 7 days
const cleanupOldData = async () => {
const { historicalData = [] } = await chrome.storage.local.get('historicalData');
const now = Date.now();
const filtered = historicalData.filter(item =>
now - item.timestamp < MAX_AGE_MS
);
await chrome.storage.local.set({ historicalData: filtered });
};
Best Practices Summary
- Monitor usage regularly: Use
getBytesInUse()before writing large data - Implement graceful degradation: Have fallback strategies when storage fills
- Choose the right storage: Use
syncfor user preferences,localfor cached data - Compress when possible: Use libraries like LZString for large JSON data
- Prune proactively: Implement automatic cleanup for old or unused data
- Test edge cases: Verify your extension handles
QUOTA_BYTESerrors gracefully
By understanding and respecting these storage quotas while implementing efficient data management strategies, you can build Chrome extensions that scale reliably and provide consistent user experiences across all devices.