Cache API Responses in Apps Script with CacheService

Every call to an external API or SpreadsheetApp takes time and counts against your quotas. CacheService lets you store results temporarily and reuse them across executions — making your scripts faster and more quota-efficient.

What is CacheService?

CacheService provides an in-memory key-value store that persists for up to 6 hours (21,600 seconds). It has three scopes:

// Shared across all users and executions of this script const cache = CacheService.getScriptCache(); // Per-user, shared across executions const cache = CacheService.getUserCache(); // Per-user, per-document const cache = CacheService.getDocumentCache();

For caching API responses shared by all users, use getScriptCache().

Cache a simple API response

function getExchangeRates() { const cache = CacheService.getScriptCache(); const cacheKey = 'exchange_rates_USD'; // Check cache first const cached = cache.get(cacheKey); if (cached) { Logger.log('Cache hit!'); return JSON.parse(cached); } // Cache miss — fetch from API Logger.log('Cache miss — fetching from API...'); const response = UrlFetchApp.fetch('https://api.exchangerate-api.com/v4/latest/USD'); const data = JSON.parse(response.getContentText()); // Store in cache for 1 hour (3600 seconds) cache.put(cacheKey, JSON.stringify(data), 3600); return data; }

Cache pattern: read-through helper

A clean wrapper that handles cache check, fetch, and store:

function cachedFetch(url, ttlSeconds = 3600) { const cache = CacheService.getScriptCache(); const key = 'fetch_' + Utilities.base64Encode(url); const hit = cache.get(key); if (hit) return JSON.parse(hit); const response = UrlFetchApp.fetch(url, { muteHttpExceptions: true }); if (response.getResponseCode() !== 200) { throw new Error(`HTTP ${response.getResponseCode()} from ${url}`); } const data = JSON.parse(response.getContentText()); cache.put(key, JSON.stringify(data), ttlSeconds); return data; } // Usage: function getWeather() { const apiKey = PropertiesService.getScriptProperties().getProperty('WEATHER_API_KEY'); const data = cachedFetch( `https://api.openweathermap.org/data/2.5/weather?q=London&appid=${apiKey}`, 900 // Cache for 15 minutes ); Logger.log(data.main.temp); }

Cache Sheet data for a custom function

Custom functions in Sheets run frequently. Caching avoids repeated API calls:

/** * @customfunction */ function GET_RATE(currency) { const cache = CacheService.getScriptCache(); const key = 'rate_' + currency.toUpperCase(); const cached = cache.get(key); if (cached) return parseFloat(cached); const response = UrlFetchApp.fetch('https://api.exchangerate-api.com/v4/latest/USD'); const rates = JSON.parse(response.getContentText()).rates; // Cache all rates at once const items = {}; Object.entries(rates).forEach(([code, rate]) => { items['rate_' + code] = String(rate); }); cache.putAll(items, 3600); return rates[currency.toUpperCase()] || 'N/A'; }

Store multiple values at once with putAll

function primeCache() { const cache = CacheService.getScriptCache(); const items = { 'config_theme': 'dark', 'config_language': 'en', 'config_version': '2.1.0', }; cache.putAll(items, 21600); // 6 hours Logger.log('Cache primed.'); } function readCachedConfig() { const cache = CacheService.getScriptCache(); const keys = ['config_theme', 'config_language', 'config_version']; const values = cache.getAll(keys); Logger.log(JSON.stringify(values)); }

Invalidate (bust) the cache

function bustCache() { const cache = CacheService.getScriptCache(); cache.remove('exchange_rates_USD'); Logger.log('Cache cleared.'); } function bustAllCaches() { const cache = CacheService.getScriptCache(); const keys = ['exchange_rates_USD', 'weather_london', 'config_theme']; cache.removeAll(keys); }

Tips

  • Cache values must be strings. Use JSON.stringify() for objects and String() for numbers.
  • Maximum cached value size is 100 KB. For larger data, split across multiple keys.
  • Maximum TTL is 21,600 seconds (6 hours). Values expire automatically.
  • putAll() and getAll() are much more efficient than multiple individual put()/get() calls.
  • Don't cache sensitive data (passwords, tokens) — use PropertiesService for persistent secrets instead.