Docs Plugins

CachingPlugin

Caches responses in memory with configurable time-to-revalidate, precise invalidation, per-request overrides, and a pluggable storage adapter contract for Redis or Memcached.

Install

import { createCachePlugin } from 'axios-retryer/plugins/CachingPlugin';

Basic usage

import { createRetryer, AXIOS_RETRYER_HTTP_METHODS } from 'axios-retryer';
import { createCachePlugin } from 'axios-retryer/plugins/CachingPlugin';

const cache = createCachePlugin({
  timeToRevalidate: 60_000,                         // 1 minute TTR
  cacheMethods: [AXIOS_RETRYER_HTTP_METHODS.GET],   // Only cache GET
  maxItems: 200,
  cleanupInterval: 5 * 60_000,                      // Prune expired entries every 5 min
});

const retryer = createRetryer().use(cache);

All options

createCachePlugin({
  timeToRevalidate: 60_000,    // Cache lifetime in ms (default: 60000)
  cacheMethods: ['get'],       // HTTP methods to cache (default: ['get'])
  maxItems: 100,               // Max cached entries; oldest evicted first (default: Infinity)
  cleanupInterval: 300_000,    // ms between expired-entry pruning (default: 300000)
  compareHeaders: false,       // Include headers in cache key (default: false)
  cacheOnlyRetriedRequests: false,  // Only cache responses from retry attempts (default: false)
  skipWhenAuthPresent: true,   // Don't cache when Authorization header is set (default: true)

  // Custom key builder — receives normalized request fields
  cacheKeyBuilder: ({ method, normalizedUrl, normalizedParams }) =>
    `${method}|${normalizedUrl}|${normalizedParams}`,

  // Custom storage adapter (e.g. Redis)
  storage: myRedisAdapter,
})

Cache invalidation

// Build a canonical cache key for an exact match
const userKey = cache.buildCacheKey({ method: 'get', url: '/api/users/1' });

// 1. Exact key invalidation
cache.invalidateCache({ exact: userKey });

// 2. Prefix invalidation (all /api/users/* entries)
cache.invalidateCache({ prefix: 'GET|/api/users/' });

// 3. RegExp invalidation
cache.invalidateCache({ pattern: /\/api\/products\/\d+/ });

// 4. Clear everything
cache.clearCache();

Per-request overrides

Override global cache settings for a single request via __cachingOptions:

// Force-cache a POST response
await retryer.axiosInstance.post('/api/summary', payload, {
  __cachingOptions: { cache: true, ttr: 30_000 },
});

// Skip caching for a specific GET
await retryer.axiosInstance.get('/api/live-prices', {
  __cachingOptions: { cache: false },
});

// Custom TTR for one request
await retryer.axiosInstance.get('/api/config', {
  __cachingOptions: { ttr: 300_000 }, // 5 minutes
});

Cache statistics

const stats = cache.getCacheStats();
console.log(stats.size);       // Number of entries
console.log(stats.averageAge); // ms since entries were cached on average

Custom storage adapter

Implement CacheStorage to back the cache with Redis, Memcached, or any persistent store:

import type {
  CacheStorage,
  CacheStorageEntry,
  CachedItem,
} from 'axios-retryer/plugins/CachingPlugin';

class RedisAdapter implements CacheStorage {
  async get(key: string): Promise<CachedItem | undefined> {
    const raw = await redis.get(key);
    return raw ? JSON.parse(raw) : undefined;
  }
  async set(key: string, value: CachedItem): Promise<void> {
    await redis.set(key, JSON.stringify(value), 'PX', value.expiresAt - Date.now());
  }
  async delete(key: string): Promise<void> {
    await redis.del(key);
  }
  async clear(): Promise<void> {
    await redis.flushDb();
  }
  async entries(): Promise<readonly CacheStorageEntry[]> {
    // Return the index for cleanup, invalidation, and maxItems enforcement
    const keys = await redis.keys('*');
    return keys.map(key => [key, { /* metadata */ } as CachedItem]);
  }
}

const cache = createCachePlugin({ storage: new RedisAdapter() });
const retryer = createRetryer().use(cache);

Security notes

⚠️
Do not share caching instances across users or tenants

Cache keys do not isolate principals by default. In SSR or multi-user server contexts, use separate retryer instances per user, or disable caching for personalized endpoints. The default skipWhenAuthPresent: true is a safety net, not a guarantee.

ManualRetryPlugin → All Plugins