Current: app:video:detail:{videoId} contains categoryId: string
New: app:video:detail:{videoId} contains categoryIds: string[]
Reason: Support multi-category association
Impact: All 58,000 video details need update
Memory Impact: +1.2 MB
Current: CategoryCachePayload.channelId (remove this)
Current: CategoryCachePayload.tags: string[] (just names)
New: CategoryCachePayload (no channelId)
New: CategoryCachePayload.tags: Array<{id, name}> (JSON objects)
New: CategoryCachePayload.tagNames: string[] (names only)
Keys Affected:
app:category:allapp:category:by-id:{categoryId}app:category:with-tags:{categoryId}Impact: Denormalization of tag data
Memory Impact: +100 KB
Current: TagCachePayload { id, name, channelId, categoryId, seq }
New: TagCachePayload { id, name, categoryId, seq } ← Remove channelId
Keys Affected:
app:tag:allapp:tag:list:{categoryId}Impact: Simplified structure
Memory Impact: -200 KB (savings)
Current: ChannelCachePayload { id, name, landingUrl, ... }
New: ChannelCachePayload {
id, name, landingUrl, ...,
categories: [{id, name}], ← NEW
tags: [{id, name}], ← NEW
tagNames: string[] ← NEW
}
Keys Affected:
app:channel:allImpact: Denormalization for quick lookups
Memory Impact: +2.5 KB
// 1. Category-to-Video Index (ZSET - sorted by addedTime)
app:video:category:index:{categoryId}:videos
→ ZSET with video IDs and scores
→ Enables efficient pagination across multiple categories
→ TTL: 2 hours
→ Impact: +12.2 MB
// 2. Video-to-Categories Lookup (SET)
app:video:categories:{videoId}
→ SET of category IDs for a specific video
→ Enables quick lookup of all categories a video belongs to
→ TTL: 24 hours
→ Impact: +7.5 MB
// 3. Category Video Count (STRING)
app:category:video:count:{categoryId}
→ INTEGER count of videos in category
→ For UI display and statistics
→ TTL: 1 hour
→ Impact: +80 KB
// 4. Tag Search Index (SET)
app:tag:search:{prefix}
→ SET of tag IDs matching a prefix
→ For tag autocomplete/search
→ TTL: 2 hours
→ Impact: +0.5-1 MB
// 5. Category Tagnames Flat (STRING)
app:category:tagnames:flat:{categoryId}
→ Space-separated lowercase tag names
→ For efficient substring search without JSON parsing
→ TTL: 24 hours
→ Impact: +400 KB
| Phase | Memory | Change | Notes |
|---|---|---|---|
| Current | ~44-49 MB | - | Before changes |
| After Core Changes | ~77-82 MB | +33 MB | Include all new indexes |
| Increase | 33 MB | 66% | Acceptable for 58K videos |
// Invalidate
app:video:detail:{videoId}
app:video:category:index:{categoryId}:videos // For EACH category
app:video:categories:{videoId}
app:category:video:count:{categoryId} // For EACH category
// Invalidate
app:tag:all
app:tag:list:{categoryId}
app:tag:search:* // All prefixes
app:category:tagnames:flat:{categoryId}
app:category:video:count:{categoryId}
// Invalidate
app:category:all
app:category:by-id:{categoryId}
app:category:with-tags:{categoryId}
app:category:video:count:{categoryId}
app:category:tagnames:flat:{categoryId}
Short-lived (refresh on update):
- app:category:video:count:{id} → 3600s (1 hour)
- app:video:category:index:{id}:videos → 7200s (2 hours)
- app:tag:search:{prefix} → 7200s (2 hours)
Medium-lived (cache 24 hours):
- app:video:detail:{id} → 86400s (24 hours)
- app:video:categories:{id} → 86400s (24 hours)
- app:category:tagnames:flat:{id} → 86400s (24 hours)
Long-lived (cache 7 days):
- app:channel:all → 604800s (7 days)
- app:category:all → 604800s (7 days)
- app:tag:all → 604800s (7 days)
libs/common/src/cache/cache-keys.ts
→ Add new key patterns
libs/core/src/cache/tag/tag-cache.builder.ts
→ Remove channelId from TagCachePayload
libs/core/src/cache/category/category-cache.builder.ts
→ Update to include tags as JSON + tagNames
→ Remove channelId
libs/core/src/cache/channel/channel-cache.builder.ts
→ Add categories, tags, tagNames to payload
libs/core/src/cache/video/
→ Create VideoCategoryIndexBuilder
→ Update video detail builder for categoryIds
apps/box-mgnt-api/src/cache-sync/cache-sync.service.ts
→ Add builders for new indexes
CACHE_SEMANTICS.md (libs/common/src/cache/)
→ Document new key patterns and semantics
Total Estimated Effort: 6-9 days
Team: 1-2 backend engineers
Risk Level: Medium (data migration required)