SuperFetch is a proxy for UrlFetchApp with additional features such as built-in caching – see SuperFetch – a proxy enhancement to Apps Script UrlFetch for how it works and what it does.
This is another in my series on SuperFetch plugins.
Caching – why bother?
Apps Script provides a caching service that’s pretty fast – usually faster than accessing the source data. More importantly there aren’t rate limits or usage charges – so if you’re using an API with such charges or disruptive rate limits (like the Twitter or Git API for example), you should keep API fetches to a minimum.
When does caching happen
When a Plugin performs a GET operation, SuperFetch first checks the cache and returns the last known value rather than going to the API.
If SuperFetch does have to access the API, it also writes the data to cache under a key generated from the API request URL, a prefix you supply (normally the default one is fine), and potentially some header options.
SupeFetch never writes the result of POST and other write operations to cache.
noCache
All SuperFetch plugins have a noCache option. When set, the Plugin doesn’t write or read any cache data. In other words, noCache: true means always go to the API
During a noCache GET, it deletes any existing cache records for that key. The idea is that if anyone is doing a noCache operation it’s because they know the cache is out of date – so best to delete it now.
Pagination
By default, SuperFetch plugins deal with pagination automatically. They unpage and return the entire dataset in a single response. There is an option to deal with pagination manually if you really want to, but in principle, since these are server based queries, it’s likely that you’ll want all the data unpaged.
For automatic unpaging, the Plugin writes the entire unpaged dataset to cache – it’s not written a page at a time, because nextPageTokens are likely to become invalid between paging sessions.
Caching limitations
First of all the Apps Script Caching service has a size limit of 100k per entry – which is not a lot. Secondly you can’t easily know if data is stale, especially if you have multiple instances of the script running.
How Superfetch deals with these limitations
Under the hood SuperFetch uses this library Apps script caching with compression and enhanced size limitations,
Size limitations
It gets over the size limitation by
- compressing all data before writing to caching and uncompressing to its original state on retrieval.
- if the compressed data is still bigger than the Apps Script limit, it spreads it over multiple cache entries and keeps a record of the keys for all those entries
The cacher handles all this in the background, so you just put or get data of any size to the library.
Staleness
The biggest complication in caching is how to deal with staleness. Since cache keys are based on how to get data, you can’t know if any particular POST type operation is going to change the data associated with that key previously.
You can use noCache to invalidate a GET operation, but that’s rather a blunt instrument.
StaleKey
Eventually all SuperFetch Plugins will support 2 additional parameters at instantiation.
Typically you won’t need to specify them (more on that later).
With stale enabled, a Plugin will store a unique value against the staleKey. It writes it to cache so any script using the same cache for this plugin will see it.
Here’s how:
- When the plugin issues any POST type requests, it updates the value in this staleKey
- When it generates key to recover data from cache, it includes this value in the key.
As a result it can never find any cache entries prior to the latest post, because the staleKey value will have changed.
Fine tuning with staleKey
Hopefully you will have realized that changing the staleKey value makes all cache entries for this Plugin unfindable, and in general that’s the safest approach. However, you can create multiple instances of the plugin, each with a different staleKey of your choosing.
Like this, if you are sure that updating some data will not affect the results returned from some other query you can use different staleKeys for each type of data.
Which CacheService to use
It’s very important to choose the correct cache service when creating your SuperFetch instance. In most cases you’ll instantiate like this.
This is because different users potentially should get different results based on what their tokenService allows. If you use ScriptCache (or DocumentCache), you’re effectively sharing cache results between multiple users – meaning they may get data not intended for them. In some cases this could be correct for public or other shared data, but generally you’ll want to use UserCache to guarantee they will just see their own data.
Links
bmSuperFetch: 1B2scq2fYEcfoGyt9aXxUdoUPuLy-qbUC2_8lboUEdnNlzpGGWldoVYg2