проектdocs/Agents/rules/data-redis-caching.md
data-redis-caching.md
Обновлён 1 апр. 2026 г., 12:41 · 0 комментариев
title: Redis Caching Strategy impact: HIGH impactDescription: Reduces database load and improves response times tags: redis, caching, performance
Паспорт документа
- Статус документа: living standard
- Актуально на: 28 марта 2026 года
- Владелец: backend/platform-команда
- Пересмотр: при изменении инженерной практики, CI/CD, архитектурных правил или локального workflow
- Область применения: внутренние rule/reference-card документы для инженерной команды
- Связанные документы:
Redis Caching Strategy
Impact: HIGH
Use Redis for caching frequently accessed, read-heavy data. Every cache entry must have a TTL to prevent stale data accumulation.
What to Cache
| Data | Key Pattern | TTL | Invalidation |
|---|---|---|---|
| Catalog queries | catalog:{hash(filters)} | 5 min | On item publish/update |
| Reference data (subjects) | ref:subjects | 30 min | On admin edit |
| Reference data (locations) | ref:locations | 30 min | On admin edit |
| Item detail | item:{slug} | 10 min | On item update |
| Popular items | popular:items | 15 min | Scheduled refresh |
| Seller profile | seller:{id} | 10 min | On seller update |
What NOT to Cache
- User-specific data (leads, reviews in editing)
- Data that changes per request (search results with user context)
- Authentication tokens (use separate Redis DB for sessions)
Implementation Pattern
@Injectable()
export class CacheService {
constructor(private readonly redis: RedisService) {}
async getOrSet<T>(key: string, ttlSeconds: number, factory: () => Promise<T>): Promise<T> {
const cached = await this.redis.get(key);
if (cached) return JSON.parse(cached) as T;
const fresh = await factory();
await this.redis.setex(key, ttlSeconds, JSON.stringify(fresh));
return fresh;
}
async invalidate(pattern: string): Promise<void> {
const keys = await this.redis.keys(pattern);
if (keys.length > 0) await this.redis.del(...keys);
}
}
// Usage in service
@Injectable()
export class CatalogService {
constructor(
private readonly catalogRepo: CatalogRepository,
private readonly cache: CacheService,
) {}
async getPublishedItems(filters: CatalogFilters) {
const cacheKey = `catalog:${this.hashFilters(filters)}`;
return this.cache.getOrSet(cacheKey, 300, () =>
this.catalogRepo.findPublished(filters)
);
}
}
Cache Invalidation
When data changes, invalidate related cache keys:
async publishItem(itemId: string) {
await this.itemRepo.updateStatus(itemId, 'PUBLISHED');
// Invalidate related caches
await this.cache.invalidate('catalog:*');
await this.cache.invalidate(`item:*`);
}
Rules:
- Every cached value must have a TTL
- Use
getOrSetpattern to avoid cache stampede - Invalidate on write, never rely on TTL alone for critical data
- Use separate Redis database for sessions vs cache