google-apps-scriptgoogle-cloud-platformurlfetchquota

Exception: Service invoked too many times for one day: premium urlfetch


I have some scripts with functions running on a trigger. Some functions are scheduled to run once per day and few every 10 mins. I am using a Google workspace account which has a quota of 100,000 calls/day for Urlfetch. I am quite sure that I haven't exceeded this quota. So, not sure why I keep getting this exception.

Exception: Service invoked too many times for one day: premium urlfetch.

Also, this exception comes for about an hour every day after which it resolves.

Please advise on the following :-

  1. Root cause and resolution
  2. Difference between urlfetch and premium urlfetch (as the exception says premium)

Solution

  • Quota exceeded errors usually tell that you are really exceeding the quota. Use logging to ensure that the logic in your code is correct and that there are no unintended repeated calls to UrlFetchApp().fetch().

    To find how many times you are actually calling UrlFetchApp.fetch(), use console.log(). One easy way to do that is to replace all UrlFetchApp.fetch(...).getContentText() calls with a call to a helper utility function such as this one:

    /**
    * Caches and logs UrlFetchApp.fetch().getContentText().
    *
    * @param {String} url The URL to fetch.
    * @param {Object} params The parameters to use in fetch.
    * @param {String} optContext Optional. An identifier string to log. Use false to skip logging.
    * @return {String} The text returned by HTTPResponse.getContentText().
    */
    function cachedUrlFetchContentText_(url, params, optContext) {
      // version 1.1, written by --Hyde, 21 March 2023
      //  - see https://stackoverflow.com/a/75705228/13045193
      const cacheKey = JSON.stringify([url, params]);
      const cache = CacheService.getScriptCache();
      let cacheHit = false;
      let result;
      let resultJson = cache.get(cacheKey);
      if (resultJson) {
        result = JSON.parse(resultJson);
        cacheHit = true;
      } else {
        result = UrlFetchApp.fetch(url, params)
          .getContentText(); // replace with .getContent() to get raw result
        resultJson = JSON.stringify(result);
        cache.put(cacheKey, resultJson, 21600);
      }
      if (optContext !== false) {
        console.log(`cachedUrlFetchContentText_ context: ${optContext || '-'} url: ${url} cacheHit: ${cacheHit}`);
      }
      return result;
    }
    

    When you use a utility function to wrap all calls to UrlFetchApp.fetch(), it is also easy to incorporate caching, as shown above. In many use cases, caching can help you avoid hitting quota limits in the first place.

    To view the logs, visit the My Executions dashboard or the Logs Explorer.

    See console, Cloud Logging and Cache Service.