# Caching Documentation This document describes all caching mechanisms in YouMusic to improve performance and reduce external API calls. ## Overview YouMusic implements a multi-layered caching strategy: 1. **Artist Information Cache** (JSON) 2. **Artist Image Cache** (Local files) 3. **Browser Cache** (localStorage & HTTP caching) --- ## 1. Artist Information Cache ### Location ``` data/cache/artists/{artist_name}.json ``` ### Purpose Cache artist metadata from Deezer and MusicBrainz APIs to avoid repeated API calls. ### Duration **30 days** (configurable via `CACHE_DURATION_DAYS`) ### Data Cached ```json { "name": "Artist Name", "image": "cache/artist_images/Artist_Name.jpg", "bio": "Type: Group • Country: US", "listeners": 1234567, "playcount": null } ``` ### Cache Flow ``` 1. User visits artist page 2. Check if {artist_name}.json exists 3. If exists & < 30 days old → Return cached data 4. If expired or missing → Fetch from API 5. Save to cache file 6. Return fresh data ``` ### Implementation - **File**: `backend/app/api/artist.py` - **Functions**: - `get_cached_artist_info()` - Read from cache - `save_artist_info_to_cache()` - Write to cache - `get_cache_path()` - Generate safe filename ### API Endpoints **Get Artist Info (with cache):** ```http GET /api/artists/{artist_name}/info ``` **Clear Single Artist Cache:** ```http DELETE /api/artists/{artist_name}/cache ``` Returns: `{"message": "Cache cleared for Artist Name"}` **Clear All Artist Cache:** ```http DELETE /api/artists/cache/all ``` Returns: `{"message": "Cleared 15 cached artists"}` --- ## 2. Artist Image Cache ### Location ``` data/cache/artist_images/{artist_name}.jpg ``` ### Purpose Download and store artist images locally to: - Reduce bandwidth - Faster loading - Offline support - Avoid external CDN dependencies ### Duration **30 days** (same as artist info) ### Image Sources 1. **Deezer API** (primary) - High quality: 1000×1000px - Format: JPG 2. **External URLs** (for streaming songs) - From YouTube/Bilibili thumbnails ### Cache Flow ``` 1. Fetch artist info from API 2. If image URL exists: a. Download image file b. Save to data/cache/artist_images/ c. Update artist info with local path 3. Serve from /cache/artist_images/ endpoint ``` ### Implementation - **File**: `backend/app/api/artist.py` - **Function**: `download_and_cache_artist_image()` - **Served via**: FastAPI StaticFiles at `/cache` ### Supported Formats - `.jpg` (primary) - `.png` - `.webp` ### File Naming Artist names are sanitized for safe filenames: - `AC/DC` → `AC_DC.jpg` - `Guns N' Roses` → `Guns_N__Roses.jpg` - `Beyoncé` → `Beyonc_.jpg` --- ## 3. Browser Cache ### Theme Preference **Storage**: localStorage **Key**: `theme` **Values**: `"light"` | `"dark"` **Duration**: Permanent (until cleared) ```typescript localStorage.setItem('theme', 'dark') const theme = localStorage.getItem('theme') ``` ### Play Mode **Storage**: localStorage **Key**: `playMode` **Values**: `"loop"` | `"shuffle"` | `"repeat-one"` **Duration**: Permanent (until cleared) ```typescript localStorage.setItem('playMode', 'shuffle') const mode = localStorage.getItem('playMode') ``` ### TanStack Query Cache **Location**: In-memory (React) **Duration**: 5 minutes (default) **Caches**: - Artist list - Playlist data - Music library - Download status ```typescript queryClient.setQueryData(['artists'], cachedData) ``` --- ## Cache Directory Structure ``` data/ ├── cache/ │ ├── artists/ # Artist metadata JSON files │ │ ├── Westlife.json │ │ ├── Taylor_Swift.json │ │ ├── Ed_Sheeran.json │ │ └── ... │ │ │ └── artist_images/ # Artist avatar images │ ├── Westlife.jpg │ ├── Taylor_Swift.jpg │ ├── Ed_Sheeran.jpg │ └── ... │ ├── music/ # Music files & thumbnails │ ├── song1.mp3 │ ├── song2.mp3 │ └── thumbnails/ │ ├── song1.jpg │ └── song2.jpg │ └── uploads/ # User uploaded files ``` --- ## Cache Management ### Automatic Expiration - **When**: File modification time > 30 days - **Action**: File deleted on next request - **Trigger**: Automatic on read ### Manual Clearing **Backend - Single Artist:** ```bash curl -X DELETE http://localhost:8000/api/artists/Westlife/cache ``` **Backend - All Artists:** ```bash curl -X DELETE http://localhost:8000/api/artists/cache/all ``` **Browser - Clear All:** ```javascript localStorage.clear() queryClient.clear() ``` --- ## Performance Impact ### Without Cache (First Request) ``` 1. Deezer API call: ~300ms 2. Image download: ~500ms 3. File save: ~50ms Total: ~850ms ``` ### With Cache (Subsequent Requests) ``` 1. Read JSON file: ~2ms 2. Serve cached image: ~5ms Total: ~7ms ``` **Speed Improvement: ~120x faster! 🚀** --- ## Cache Statistics ### Storage Usage (Example) ``` Artist Info Cache: - 100 artists × 2KB = 200KB Artist Images: - 100 artists × 150KB = 15MB Total Cache Size: ~15.2MB ``` ### API Call Reduction ``` Without cache: - 100 artists × 2 API calls = 200 calls With cache (30 days): - 100 artists × 2 calls / 30 days = ~7 calls/day Reduction: 97% fewer API calls! 📉 ``` --- ## Configuration ### Cache Duration **File**: `backend/app/api/artist.py` ```python CACHE_DURATION_DAYS = 30 # Adjust as needed ``` ### Cache Directories **File**: `backend/app/core/config.py` ```python MUSIC_DIR = os.path.join(BASE_DIR, "data", "music") # Cache created automatically in data/cache/ ``` --- ## Monitoring Cache ### Check Cache Size ```bash # Artist info cache du -sh data/cache/artists/ # Artist images cache du -sh data/cache/artist_images/ # Total cache du -sh data/cache/ ``` ### List Cached Artists ```bash # Count cached artists ls -1 data/cache/artists/ | wc -l # List all cached artists ls -1 data/cache/artists/ ``` ### Check Cache Age ```bash # Find old cache files (>30 days) find data/cache/artists/ -type f -mtime +30 # Delete old cache files find data/cache/artists/ -type f -mtime +30 -delete ``` --- ## Troubleshooting ### Issue: Artist image not showing **Check:** 1. Image file exists: `ls data/cache/artist_images/` 2. Static files mounted: Check `main.py` - `/cache` route 3. Network tab: Check actual URL being requested 4. Cache JSON: Check if `image` field has correct path **Solution:** ```bash # Clear and refresh cache rm data/cache/artists/{artist_name}.json rm data/cache/artist_images/{artist_name}.jpg ``` ### Issue: Cache not clearing **Check:** 1. File permissions: `ls -la data/cache/` 2. API endpoint: `curl -X DELETE .../cache` **Solution:** ```bash # Manual clear rm -rf data/cache/artists/* rm -rf data/cache/artist_images/* ``` ### Issue: Old data being served **Cause:** Cache not expired yet **Solution:** ```bash # Force refresh by deleting cache curl -X DELETE http://localhost:8000/api/artists/{name}/cache # Or delete manually rm data/cache/artists/{artist_name}.json ``` --- ## Best Practices ### ✅ Do's - Let cache expire naturally (30 days) - Use cache clearing endpoints for manual refresh - Monitor cache size periodically - Keep cache duration reasonable (7-90 days) ### ❌ Don'ts - Don't manually edit cache JSON files - Don't commit cache to git (add to .gitignore) - Don't set cache duration too short (<1 day) - Don't disable caching (performance impact) --- ## Future Improvements ### Planned Features 1. **Cache Warming** - Pre-fetch popular artists 2. **Smart Expiration** - Expire based on artist popularity 3. **Cache Analytics** - Track hit/miss ratios 4. **CDN Integration** - Upload images to CDN 5. **Progressive Images** - Blur-up loading ### Potential Optimizations 1. **WebP Conversion** - Smaller file sizes 2. **Image Resizing** - Multiple sizes for different views 3. **Lazy Loading** - Only load visible images 4. **Service Worker** - Offline-first approach --- ## Related Files ### Backend - `backend/app/api/artist.py` - Cache implementation - `backend/main.py` - Static file serving - `backend/app/core/config.py` - Configuration ### Frontend - `frontend/src/components/artist/ArtistsPage.tsx` - Display avatars - `frontend/src/components/artist/ArtistDetailPage.tsx` - Hero images - `frontend/src/App.tsx` - Theme/mode caching --- ## Summary YouMusic uses a three-tier caching system: 1. **API Data Cache** (30 days) - Artist metadata 2. **Image File Cache** (30 days) - Artist avatars 3. **Browser Cache** (permanent) - User preferences This reduces: - API calls by **97%** - Page load time by **120x** - Bandwidth usage by **~15MB per 100 artists** All caches auto-expire and can be manually cleared via API endpoints. --- **Last Updated:** 2024-10-30 **Version:** 1.0.0