OpenPWAStore
Back to News
Guide · May 19, 2026

Your PWA's survival depends on storage quota behavior

How to manage storage quotas, test eviction behavior, and request persistent storage for installed PWAs.

OpenPWA Editorial6 min read
Your PWA's survival depends on storage quota behavior cover

Why storage quota breaks PWAs

Your PWA works offline. Users store documents, cache images, save drafts in IndexedDB. Everything is fine.

Then the browser runs out of storage. It starts evicting data to make room. Your IndexedDB database gets partially deleted. Your cache entries vanish. Users lose work, see broken UI, and uninstall your app.

The problem: exceeding quota doesn't produce a clean error. Instead, the browser starts evicting data "often without a signal your worker can react to," according to a PWA implementation guide on handling service worker updates.

The browser storage model

Modern browsers use a per-origin storage quota that applies to IndexedDB, Cache API, and other storage APIs. The actual limit varies by browser, device, and storage pressure:

  • Chrome: Typically 60-80% of available disk space per origin
  • Safari: Often 1 GB per origin on desktop, less on mobile
  • Firefox: Similar to Chrome but with platform-specific adjustments
  • Mobile browsers: Significantly lower limits, often 50-250 MB per origin

Installed PWAs added to the home screen get better treatment—in some browsers like Safari, they're exempt from the seven-day cap that applies to ordinary web apps. But they're not exempt from storage pressure.

Storage estimation

Before writing data, estimate your usage:

const { usage, quota } = await navigator.storage.estimate();
const usageMB = usage / (1024 * 1024);
const quotaMB = quota / (1024 * 1024);
const usedPercent = (usage / quota) * 100;

console.log(`Using ${usageMB.toFixed(2)} MB of ${quotaMB.toFixed(2)} MB (${usedPercent.toFixed(1)}%)`);

Security note: Telemetry and fingerprinting

Storage estimation reveals disk usage patterns that can serve as a weak fingerprinting vector. Don't log exact sizes in production without user consent. Use percentage ranges instead (e.g., "using 10-20% of quota") to reduce fingerprinting risk while still providing useful feedback.

Persistent storage workflow

Persistent storage tells the browser "don't evict this data unless the user explicitly removes it." It's not a guarantee against all eviction, but it moves your PWA to the front of the line when storage runs out.

Request persistent storage

async function requestPersistentStorage() {
  if (navigator.storage && navigator.storage.persist) {
    const persisted = await navigator.storage.persist();
    if (persisted) {
      console.log('Storage is now persistent');
    } else {
      console.log('Storage is not persistent');
      // Browser denied the request—guide user to clear space or reconsider
    }
  }
}

// After user installs your PWA or completes onboarding
requestPersistentStorage();

Don't request persistent storage immediately on page load. The browser will deny it. Instead:

  1. Explain why: "We store your documents locally so you can work offline. This requires permanent storage on your device."
  2. Request after deliberate action: User installs your PWA, enables offline mode, or creates their first document.
  3. Provide an alternative: If the user denies, offer cloud sync instead of local storage.

Platform differences

| Browser | Persistent storage behavior | Notes | |---------|---------------------------|-------| | Chrome | Requests show a permission prompt | User can deny storage quota requests | | Safari | Automatically grants to installed web apps | iOS PWA "Add to Home Screen" enables persistence | | Firefox | Similar to Chrome with prompts | May require user interaction first | | Edge | Follows Chromium behavior | Consistent with Chrome |

The eviction testing checklist

Before shipping, test how your PWA behaves when storage runs out:

Setup test environment

  1. Use Chrome DevTools > Application > Storage to inspect current usage
  2. Manually fill storage with dummy data until quota is nearly full
  3. Monitor IndexedDB errors and cache failures

Test scenarios

  • [ ] Attempt to write to IndexedDB when quota is exceeded
  • [ ] Navigate to cached offline pages after eviction
  • [ ] Retry failed cache writes with proper error handling
  • [ ] Show user-friendly messages for "storage full" rather than generic errors
  • [ ] Verify data integrity after partial eviction (some entries survive, others don't)

Recovery workflow

When you detect quota exceeded or data loss:

  1. Inform the user: "Your device is running low on storage. Some local data may be unavailable."
  2. Offer clear actions: "Clear cached images" or "Enable cloud sync"
  3. Gracefully degrade functionality: Allow read-only access, suggest re-downloading data
  4. Don't silently fail: Log quota errors to your error tracking, but always show user messaging

What goes wrong in production

Common mistakes

  1. Ignoring quota: Uncapped IndexedDB grows forever until browser evicts everything
  2. No error handling: Scripts throw QuotaExceededError and crash the page
  3. Silent data loss: Cache success callbacks never fire, but the UI shows cached content
  4. Per-user assumptions: 500 MB is fine for your device, but your users have 64 MB

Real-world failure pattern

User opens your PWA on a phone. They download 20 PDF documents (200 MB). You cache all images on every page navigation (150 MB). Quota hits 250 MB. The browser evicts your oldest cache entries. User navigates back. Images are missing. User sees broken UI. Your PWA loses a user.

Best practices for production PWAs

  1. Cache intelligently: Cache-first for critical assets (app shell), network-first for dynamic content. Don't cache everything forever.
  1. Monitor storage usage in analytics: Track median/quartile storage usage by device type. If 25% of mobile users hit >80% quota, reduce cache limits.
  1. Use Cache cleanup: When updating caches, remove old versions instead of accumulating them. Implement cache expiration for media assets.
  1. Provide user control: Let users clear cached data from settings. Make it obvious how much space your PWA uses.
  1. Test on low-storage devices: Emulate 64 MB, 128 MB, 256 MB storage limits in Chrome DevTools. Don't assume your users have abundant storage.

What this means for your PWA architecture

Storage management isn't a feature—it's architecture. Your offline strategy must account for:

  • Quota limits per platform
  • Eviction behavior under pressure
  • Persistent storage consent flow
  • Graceful degradation when data is unavailable

If you're building a document editor, consider:

  • Local-first by default, cloud backup as fallback
  • Partial document support (cache structure, load content on demand)
  • User-guided cache management (clear old drafts, archive unused files)

If you're building a media app, consider:

  • Progressive loading (cache first few items, stream the rest)
  • Cache expiration for media after 30 days
  • Optional high-quality downloads that require explicit user action

The next step

Storage quota management is one piece of a larger offline-ready strategy. The next piece is background sync—queuing offline actions and replaying them when connectivity returns. Combined with quota-aware caching and graceful degradation, background sync turns offline from a fallback mode into a first-class feature.

Don't let storage limitations break your PWA's promise. Estimate, monitor, persist, and test. Your users expect their data to survive—even when the browser decides otherwise.