본문으로 건너뛰기
cccskills
무료GitHub에 공개

caching-strategies

When improving read performance and reducing database load.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

연동 도구Redis
설치 방법 보기

포함된 파일(1)

  • SKILL.md8.0 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Caching Strategies

Purpose

Databases are slow; caches are fast. This skill teaches teams to strategically cache frequently accessed data in fast storage (Redis, Memcached) to intercept requests before they hit the database, dramatically reducing latency and database load. Caching is NOT a substitute for proper database optimization.

When to use

  • System is experiencing high latency on read-heavy API endpoints
  • Database CPU/Memory usage is constantly peaking due to repeated queries
  • Designing a new system expecting massive read throughput
  • Content rarely changes but reads happen constantly

When NOT to use

  • Before optimizing database queries (optimize first, cache second)
  • For data that changes frequently or is highly personalized
  • When consistency is more important than performance
  • As a quick fix for poor application architecture

Inputs required

  • Slow query logs or endpoint metrics
  • Cache infrastructure (Redis, Memcached)
  • Read/write patterns of the data
  • Acceptable staleness window (TTL)

Workflow

  1. Identify Bottlenecks: Profile APIs to find read-heavy, slow-changing data (user profiles, static config, product catalogs)
  2. Measure Access Patterns: How often is data read vs. written? How large? How old can it be?
  3. Select Strategy:
    • Cache-Aside: App checks cache; on miss, fetches DB, writes cache
    • Write-Through: App writes to cache and DB simultaneously
    • Write-Behind: App writes to cache only; batch updates to DB later (use cautiously)
  4. Set Eviction Policy: Assign Time-To-Live (TTL) values based on business tolerance for stale data
  5. Handle Invalidation: Implement cache invalidation logic on mutations (UPDATE/DELETE)
  6. Prevent Stampedes: Implement caching locks or staggered TTLs to prevent multiple clients fetching from DB simultaneously when a key expires
  7. Add Monitoring: Track cache hit rates, eviction rates, and staleness

Rules

  • MUST treat cache as ephemeral (can disappear at any time)
  • MUST NOT cache highly personalized or sensitive data (PII) in shared caches
  • MUST ALWAYS implement fallback to primary data store on cache failure
  • MUST set TTL values (no infinite cache)
  • MUST invalidate cache on mutations (UPDATE, DELETE operations)
  • MUST use separate caches for different data types/sensitivity levels
  • MUST NOT use cache as source of truth

Anti-patterns

  • Infinite TTL: Storing keys without expiration (leads to unbounded memory, stale data)
  • Premature Caching: Adding Redis before the database is properly indexed
  • No Fallback: Cache failure crashes the application
  • Over-Caching: Caching everything including rarely-used data (wastes cache memory)
  • Forgetting Invalidation: Updating database but not cache (stale data served indefinitely)
  • Cache Stampede: All requests hit cache miss simultaneously, causing DB spike
  • Storing Mutable Objects: Storing references to objects that change, returning stale mutations

Failure conditions

  • Cache becomes source of truth (data lost if cache clears)
  • No fallback logic when cache is unavailable
  • Cache miss causes cascading database failures
  • Stale data leads to data corruption
  • Cache stampede (all requests simultaneously fetch from DB)

Validation checklist

  • Cache is treated as optimization layer, not data store
  • Fallback to primary data store on cache miss works
  • TTL is set (no infinite cache)
  • Cache invalidation triggered on data mutations
  • Cache hit rate > 80% for target queries
  • No cache stampede when keys expire simultaneously
  • Sensitive data not cached (or encrypted if cached)
  • Cache memory usage monitored (no unbounded growth)
  • Stale data handling defined (acceptable staleness window)
  • Monitoring dashboards show hit rate and eviction rate

Output format

  • Cache-Aside wrapper: Function that checks cache, handles miss, populates cache
  • Invalidation triggers: ON UPDATE/DELETE, clear cache key
  • Configuration: TTL values, eviction policy, cache key naming convention
  • Monitoring: Hit rates, eviction rates, staleness metrics
  • Documentation: Which data is cached, staleness tolerance, fallback behavior

Security considerations

  • Sensitive data MUST NOT be cached or only in encrypted form
  • Cache keys MUST be predictable (not guessable)
  • Access control MUST be enforced (not all users can access all cache keys)
  • Sensitive data MUST be masked in monitoring logs
  • Cache MUST be protected from unauthorized access

Agent execution notes

  • Agent MAY: Add cache checks, implement invalidation, set TTL, add monitoring
  • Agent MUST NEVER: Use cache as source of truth, forget fallback logic, set infinite TTL
  • Agent MUST ASK: Before caching sensitive data, before major caching strategy change
  • Agent MUST VALIDATE: Fallback logic works, TTL configured, invalidation on mutations

Example

❌ Anti-pattern (No fallback, infinite TTL, no invalidation):

// WRONG: No fallback if cache fails
const getUser = async (userId) => {
  return redis.get(`user:${userId}`); // Fails if Redis is down
};

// WRONG: Infinite TTL
redis.set(`config:app-settings`, settings); // Never expires = stale data forever

// WRONG: No invalidation on update
async function updateUser(userId, data) {
  await db.users.update(userId, data);
  // Forgot to clear cache - stale data served
}

// WRONG: Cache stampede - all requests hit DB when key expires
const getExpensiveData = async () => {
  const cached = await redis.get('expensive-data');
  if (!cached) {
    // All concurrent requests hit this - DB spike
    const data = await slowQuery();
    await redis.set('expensive-data', data, { ex: 3600 });
    return data;
  }
  return cached;
};

✅ Correct pattern (Fallback, TTL, invalidation, stampede prevention):

// CORRECT: Fallback to database on cache miss or failure
const getUser = async (userId) => {
  try {
    const cached = await redis.get(`user:${userId}`);
    if (cached) return JSON.parse(cached);
  } catch (e) {
    logger.warn('Cache miss, falling back to DB', e);
  }
  
  // Fallback to DB
  const user = await db.users.findById(userId);
  
  // Repopulate cache
  try {
    await redis.setex(`user:${userId}`, 3600, JSON.stringify(user)); // 1 hour TTL
  } catch (e) {
    logger.warn('Failed to cache, but returning DB data', e);
  }
  
  return user;
};

// CORRECT: TTL on all cache entries
redis.setex('config:app-settings', 86400, JSON.stringify(settings)); // 24 hour TTL

// CORRECT: Invalidate cache on mutations
async function updateUser(userId, data) {
  await db.users.update(userId, data);
  await redis.del(`user:${userId}`); // Clear specific key
}

// CORRECT: Prevent cache stampede with locks
const stampedeLock = new Mutex();
const getExpensiveData = async () => {
  const cached = await redis.get('expensive-data');
  if (cached) return JSON.parse(cached);
  
  // Use lock to ensure only one request fetches from DB
  return stampedeLock.runExclusive(async () => {
    // Double-check if another request already populated cache
    const cached = await redis.get('expensive-data');
    if (cached) return JSON.parse(cached);
    
    const data = await slowQuery();
    await redis.setex('expensive-data', 3600, JSON.stringify(data));
    return data;
  });
};

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

When designing and implementing web interfaces to ensure they are usable by everyone.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

KraitDev/skiLL.Md62026년 6월 8일 업데이트

When creating or extending an HTTP API for client consumption.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

KraitDev/skiLL.Md62026년 6월 8일 업데이트

When configuring automated build, test, and deployment workflows for a repository.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

KraitDev/skiLL.Md62026년 6월 8일 업데이트

When asynchronously reviewing peer code before merging into the main branch.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

KraitDev/skiLL.Md62026년 6월 8일 업데이트

When addressing slow application endpoints, high database CPU usage, or standardizing data access patterns.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

KraitDev/skiLL.Md62026년 6월 8일 업데이트

When isolating and fixing unpredictable or complex software bugs.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

KraitDev/skiLL.Md62026년 6월 8일 업데이트

KraitDev의 스킬 모두 보기

이 스킬의 문제 신고