All articles

Technical

Storage Quotas and IndexedDB Persistence in Android TWAs

September 14, 2026 · 9 min read

When you wrap a Progressive Web App inside a Trusted Web Activity, users expect the application to behave like a native client. This means that local databases, application states, drafts, and media caches must persist across app restarts and system reboots. However, because a TWA is powered by the device's system browser engine, its local storage is subject to web storage quotas and browser-managed eviction policies. Understanding how to manage these limits and request persistent storage is crucial to prevent unexpected data loss.

How Android and Chrome Handle TWA Storage

A Trusted Web Activity shares the storage engine of the underlying system browser, which is typically Google Chrome on Android devices. This architecture means your app does not run in a completely isolated sandboxed environment like a traditional WebView. Instead, it shares Chrome's global storage pool, although data is scoped to your specific web origin.

By default, browser engines categorise all web storage as temporary. Under low-disk conditions, Android's kernel or Google Chrome itself can initiate storage cleanup. If a user runs out of space on their device, the browser will silently clear temporary web storage on a least-recently-used basis. This cleanup can wipe your IndexedDB instances, Cache Storage API assets, and localStorage keys, breaking offline functionality and erasing user progress.

The Web Storage Management Architecture

Chromium divides web storage into two classifications: Best-Effort storage and Persistent storage. Understanding the differences between these types helps developers design resilient offline architectures.

Storage TypeEviction RiskStandard APIs AffectedHow to Secure
Best-EffortHigh (When device storage is low)IndexedDB, Cache Storage, localStorageRequest explicit persistence via StorageManager
PersistentNone (Only deleted if user uninstalls app)IndexedDB, Cache Storage, localStorageSuccessfully invoke navigator.storage.persist()

By default, every TWA starts in the Best-Effort category. If the device runs low on disk space, Chrome will actively clear data from Best-Effort origins starting with the least recently used application until the storage pressure is relieved.

Querying Available Storage Programmatically

Before writing data or relying on offline databases, your web application should actively query the device to see how much space is available. The StorageManager API provides a standardized interface to check storage usage and quotas.

You can execute the estimation code inside your web application logic to determine if the device has enough space to cache assets or store user database records. This is done by checking the quota and usage values returned by the estimator:

if (navigator.storage && navigator.storage.estimate) {

navigator.storage.estimate().then(function(estimate) {

var usageInMebibytes = (estimate.usage / (1024 * 1024)).toFixed(2);

var quotaInMebibytes = (estimate.quota / (1024 * 1024)).toFixed(2);

console.log('Used: ' + usageInMebibytes + ' MB of ' + quotaInMebibytes + ' MB');

});

}

Using this data, your application can dynamically alter its caching behavior. For example, if the remaining storage quota is low, your TWA can disable rich media caching and prioritize basic structural data inside IndexedDB.

Requesting Storage Persistence in a TWA

To shield your database and offline cache from background eviction, you must request that your origin be placed in the Persistent storage category. This is accomplished using the StorageManager API. When persistence is granted, Chrome guarantees that the data will not be evicted during low-disk states.

To request persistence, you must call the persist method on the storage object:

if (navigator.storage && navigator.storage.persist) {

navigator.storage.persist().then(function(granted) {

if (granted) {

console.log('Storage will not be cleared by the system.');

} else {

console.log('Storage is vulnerable to eviction.');

}

});

}

Whether Chrome grants this request automatically depends on several browser-internal heuristics. In a standard mobile browser, Chrome might deny the request unless the user has added the PWA to their home screen or has high engagement with the site. However, within a Trusted Web Activity, the relationship is different. Because the user has installed your app through the Google Play Store, the underlying browser engine recognises the deep integration and is highly likely to grant the persistent storage request automatically without prompting the user.

Checking Your App's Persistence Status

You can also programmatically inspect whether your application has already been granted persistent status during startup. This allows your app to display warnings or attempt re-requests if the storage state changes:

if (navigator.storage && navigator.storage.persisted) {

navigator.storage.persisted().then(function(persisted) {

if (persisted) {

console.log('App storage is secure.');

} else {

console.log('App storage is running in temporary mode.');

}

});

}

Designing a Resilient Data Architecture

Even with persistence granted, relying entirely on client-side storage is an anti-pattern for critical user data. A robust TWA should employ a layered data synchronisation strategy:

  • Use IndexedDB for local staging: Treat IndexedDB as a highly performant, queryable offline cache for your user's actions.
  • Queue operations offline: Store pending changes in a queue inside IndexedDB when the user is disconnected.
  • Leverage Service Workers: Use a service worker with background sync capabilities to upload queued transactions to your primary cloud database as soon as network connectivity is restored.
  • Handle storage errors gracefully: Always implement try-catch blocks around database write operations. If an write fails due to a QuotaExceededError, prompt the user to free up device storage or clean up non-essential caches programmatically.

By implementing storage estimation, requesting persistent storage status, and maintaining a cloud-backed architecture, you can ensure that your Trusted Web Activity offers the reliable, high-performance offline experience expected of a native Android application.

Ready to ship your Android app?

Paste your PWA URL, get a signed APK and a Google Play ready AAB in minutes.

Build my app