Qadam Roadmap
проект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

DataKey PatternTTLInvalidation
Catalog queriescatalog:{hash(filters)}5 minOn item publish/update
Reference data (subjects)ref:subjects30 minOn admin edit
Reference data (locations)ref:locations30 minOn admin edit
Item detailitem:{slug}10 minOn item update
Popular itemspopular:items15 minScheduled refresh
Seller profileseller:{id}10 minOn 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 getOrSet pattern to avoid cache stampede
  • Invalidate on write, never rely on TTL alone for critical data
  • Use separate Redis database for sessions vs cache