What is the Service Worker ⚙️ Cache Storage Limit? How Much Your Progressive Web App (PWA) Can Store
Service workers enable web sites to work offline using the Cache API. Developers need to design the logic to manage how site assets are persisted in storage.
This can lead to many challenges for developers to solve when planning their caching strategies.
How much is too much? And what is the minimum my application needs?
Page assets come in many forms, HTML, CSS, JavaScript, images and font files are obvious. These are all classified as URL addressable. This means you can type a URL in the browser address bar and retrieve the file.
Your origin (domain name) is given a certain amount of free space to do what it wants with. That free space is shared between all origin storage: LocalStorage, IndexedDB, Filesystem, and of course Caches. The amount available to service worker caching isn't defined in the specification. The amount varies by browser depending on device and storage conditions.
Files are not the only content that can be cached. localStorage is great to persist key value pairs where the values are strings. IndexedDB is more robust and can store many more types of data efficiently. I think of it a a light weight document database in the browser. appCache and service worker cache persist files, URL addressable resources to be technically correct.
But service worker cache is not the only browser storage medium you need to monitor. In addition to the service worker cache size limit you should also ask the following questions:
- What is the IndexedDB size limit?
- What is the localStorage size limit?
You could add appCache to the mix, but of course that is moot when a service worker is registered. Plus appCache is being deprecated by all browsers today.
How much space do you get and what happens when that space runs out?
The good news is you should have more than enough space to cache the assets you need to make your web site work offline. That is of course unless your site is a little on the obese side or just massive amount of pages and images.
Browsers have settled on common pattern when it comes to available space. Of course, since this is more of a gentleman's agreement among browsers it could change and vary by browser.
At the September 2017 Microsoft Edge Developer Summit Ali Alabbas shared the general rule user agents are reaching consensus when it comes to storage quota.
The amount of storage is dependent upon how much available disk space the customer's device has. The general range is 50MB over 20GB. Before you get all excited about 20GB of storage you still need to be responsible.
The common rule is 20% of available space or the following breakdown:
<= 8gb="" free="" -="" 50mb32-128gb="" 4%="" of="" volume="" size<="" p="">
128GB - 4% or 20GB, whichever is smaller
Remember those gigabytes must be moved across the wire and your customer may not appreciate you caching your entire website over their cellular data plan. This is why Amazon does not cache their entire site using a service worker!
These storage capacity and quota rules tend to be honored by Microsoft Edge, FireFox, Chrome and Opera.
Since mobile devices account for the vast majority of web traffic these days that is what I target when designing a caching strategy. The average consumer mobile device is roughly the equivalent of a Nexus 5 phone. Once, big bulky apps are installed and you account for photos, videos and music downloads there is little to no free space on the average device.
iOS Safari Service Worker Cache Limit
Oh Apple, why do you always have to complicate things?
A drawback of the service worker cache specification is the lack of a capacity or storage limit rule or algorithm. This means each browser vendor decides cache limits and invalidation strategy.
Up to this point Apple has decided to limit the service worker cache storage limit to roughly 50MB. It is actually limited to 50MiB, which equates to about 52MB. It is also allocated per 'partition', which is sort of a complicated concept related to iFrames.
But the story does not end there. No it last for about 2 weeks, literally.
This is not 100% true. If the user adds the PWA to the homescreen iOS will persist the cache for a long period of time. It feels like it is more or less permanent.
The caches are also shared when the user opens the PWA in Safari as well as from the homescreen. Prior to iOS 14 the two use cases kept separate storage. So things have gotten better.
The way Apple has chosen to implement Progressive Web Application persistence is, well odd. A PWA that goes unused for a 'few weeks' (we think it is 2 weeks) the iOS device deletes or purges the stored values. That is unless it has been added to the homescreen.
Not exactly the most user friendly policy and definitely not favorable to a business using service workers to provide better user experience.
If you are wondering why Apple has chosen this path, it is nothing new, for them. They have always had a very aggressive history with limiting how much content can be cached. They try to error on the side of limiting caching to make sure the device has storage available.
And if you have every looked at the size of native apps on iOS you would understand why storage is at a premium on iOS. They are huge!
This means you will need to plan accordingly. While most sites wont have an issue with the 50MiB storage limit, some will.
But 50MBs, what can you do?
I always implement some sort of invalidation rules in my service workers, which means my PWAs have controllable cache that wont hit quota limits.
I hate having to create some sort of polyfil or special case logic for a specific browser or device, but maybe this is one you need to create a special storage algorithm.
IndexedDB (IDB) can be your fallback. If you are not familiar with IDB it is an unstructured data store, like MongoDB and other NoSQL databases.
Despite Apple taking forever to support IDB it has been supported since Safari 8. The good news is the iOS Safari IndexedDB limit is up to 500MB*.
Take that 500MB as a low end average. I have stored a few GB in iOS Safari in some of my testing. I am currently working on more than one project to persist audio and video files in IDB instead of service worker cache for offline access.
If the size of free disk space is over 1 GB, the default limit is 500 MB; otherwise it ishalf the free disk space.
This is good news. At least you have a fallback to store more data if needed. Plus IDB is available within your service worker!
The Storage API
A new web platform feature shipping today is the Storage API. Currently Chrome and Opera are the only browsers shipping support, but others should join soon.
Because this is a new feature you should only access the storage estimator after checking for support. This can be done by verifying the storage object (technically StorageManager) exists in the navigator. After that you should verify the estimate method belongs to the StorageManager.
if ('storage' in navigator && 'estimate' in navigator.storage) {
navigator.storage.estimate()
.then(function(estimate){
console.log(`Using ${estimate.usage} out of ${estimate.quota} bytes.`);
});
}
The estimate method returns a promise that resolves an instance of a StorageEstimate object. This has two properties, usage and quota. Both are conservative approximations of the bytes associated with the value. The usage property is an estimate of how much you have cached. The quota property is a close estimate of how many bytes available to store content.
The values are in bytes, which means to convert to Megabytes you should divide by 1,000,000 (or 1048576 is you want to use 1024 as your kilobyte standard).
As you can see I have used 18MB (mostly caching product images) of the 33GB I have available.
Again, don't architect for 30+GB of storage. This is the exception as most are on phones.
If I use my goal of limiting my storage to 35MB then I need a mechanism in place to purge files from cache. The Fast Furniture demo site represents a common e-commerce presence, with a large amount of product images. They account for over 90% of the amount cached.
In my upcoming Progressive Web Application course I go into detail how you might create an cache management system. The Fast Furniture site uses multiple caches with different rules applied to different asset types. Product images have their own cache and a limit of how many files can be stored at a given time.
To make it more complex you could extend to logic to account for the average asset size and adjust your rules. For example Fast Furniture uses responsive images, which means I might be able to store more product images. Of course that is subject to the available quota.
Don't worry if this sounds complicated, it does not have to be complex. I always say start out simple and grow from there.
Summary
Understanding how much storage is available to your application is important when planning your experience. You need to find a good balance between caching everything and caching responsibly.
Browsers are reaching a general consensus as to what constitutes a proper storage capacity rule. As with all things in the developer space it all depends, mostly on the consumer's device.
Since most visitors are on a mobile device, you should plan for about 50MB of available space. This should keep you within a safe zone that enables you to create a good experience without consuming the user's bandwidth.
As the available quota increases you could also increase the amount of content you cache.