The Discover Cache System implements smart server-side caching for the discovery endpoint with automatic daily updates and fallback mechanisms.
Request for discover data
↓
Check if cache exists?
├─ YES → Serve cache immediately
│ ├─ Check if expired (24h)?
│ │ ├─ NO → Return cache (DONE)
│ │ └─ YES → Return cache + fetch fresh in background
│ └─ On fresh data: Compare hash
│ ├─ Different → Update cache
│ └─ Same → Reset 24h timer only
└─ NO → Fetch fresh from API
└─ Save to cache for next time
- Location:
.cache/discover-cache.json(server filesystem) - Metadata:
.cache/discover-cache-meta.jsonlastUpdated: Timestamp of last updatehash: SHA-256 hash of data (for change detection)
- TTL: 24 hours
- Cache is served immediately while being checked
- If cache is older than 24h, fresh data is fetched in background
- Hash comparison ensures only actual changes trigger updates
- Timer resets even if data is unchanged (prevents unnecessary fetches)
- All responses are hashed
- Only saves if hash differs (prevents unnecessary I/O)
- Metadata tracks both timestamp and hash for optimal updates
Core caching service with these functions:
getCachedDiscover() // Get cached data
getDiscoverWithCache(fetchFresh) // Smart fetch with caching
clearDiscoverCache() // Manual cache clearNew server action:
fetchDiscoveryCachedAction(token) // Uses smart cacheUpdated to:
- Import
fetchDiscoveryCachedAction - Extract and display
introductionsfrom discover response - Show editorial featured picks section
Static fallback data with full discover structure:
status: API response statusmessage: Success/error messageintroductions: Editorial featured content arrayresult: Object with numbered recommendation categories
{
"status": "200",
"message": "success",
"introductions": [
{
"id": "1",
"title": "Artist Name",
"description": "Track description...",
"image": "https://...",
"thumb_image": "https://...",
"middle": "Track Name",
"button_name": "Listen Here",
"app_url": "item.detail.html?i=..."
}
// ... more introductions
],
"result": {
"1": [ // Category 1
{ track_name, artist_name, ... }
// ... more tracks
],
"2": [ // Category 2
{ track_name, artist_name, ... }
// ... more tracks
]
// ... more categories
}
}✅ Performance: Cached responses served instantly ✅ Reliability: Fallback to cache if server is down ✅ Freshness: Updated automatically once daily ✅ Efficiency: Only updates on actual data changes ✅ User Experience: No loading delays on repeat visits ✅ Server Load: Reduced API calls with 24h batching
The system logs its actions for debugging:
✅ Discover cache saved successfully
🔄 Serving from cache
⏰ Cache expired (1440 minutes old)
🔃 Updating cache in background...
✓ Cache is still current
📥 No cache found, fetching fresh data...
⚠️ Error occurred, falling back to cache
🗑️ Discover cache cleared
import { clearDiscoverCache } from '@/services/discoverCache.service';
// Clear the cache to force fresh fetch
await clearDiscoverCache();- Cache Read Fails → Tries to fetch fresh
- Fresh Fetch Fails → Falls back to existing cache
- Both Fail → Throws error (client handled)
- File System Issues → Gracefully logs and continues
- Cache Hit: ~1ms (filesystem read)
- Cache Miss: Network latency (API call)
- Update Check: ~5ms (hash comparison)
- Memory Impact: ~500KB for typical discover data
- Redis caching for multi-server deployments
- Incremental cache updates (partial refreshes)
- Cache versioning for API schema changes
- Analytics on cache hit rates
- Configurable TTL per data type