Skip to main content

Caching

All external API calls go through a cache-first strategy to minimize rate limit hits and improve response times.

How it works

Request arrives


  Is forceRefresh set? ──Yes──▶ Call external API
      │No                              │
      ▼                                ▼
  Check cache                    Write to cache
      │                                │
      ▼                                ▼
  Fresh? (within TTL) ──Yes──▶ Return cached data
      │No

  Call external API

      ├── Success ──▶ Write to cache ──▶ Return fresh data

      └── Failure ──▶ Return stale cache (with _stale: true)

Cache TTLs per service

ServiceCache TTLNotes
OpenPanel60 secondsLive visitors: 15 seconds
BetterStack1 minute
Sentry2 minutesProjects: 10 minutes
Linear2 minutesTeams: 1 hour
GitHub2 minutes
Vercel2 minutesDomains: 5 minutes
RevenueCat5 minutesRate limited: 5 req/min
Google Search Console5 minutes
Open Collective5 minutes
App Store Connect15 minutesRate limited: 200 req/min

Stale fallback

When an external API call fails (network error, rate limit, etc.), the system falls back to the most recent cached data, even if it’s past its TTL. The response includes a _stale: true flag so the UI can indicate the data may not be current.

Cache storage

Cache is stored in the api_cache table of your configured database provider. See Database Providers.

Force refresh

Pass forceRefresh: true to bypass the cache and fetch fresh data. This is used by the Backup System to proactively warm the cache.