When to use this
- Adding caching to a slow read path, and need to choose TTL/invalidation strategy, not just "add a cache."
- An existing cache is serving stale data and the invalidation logic needs review.
- Not for adding caching purely speculatively without a measured read-latency or load problem to justify it -- caching adds complexity and a new failure mode; only add it where warranted.
The skill file
Copy this verbatim. It's written in the SKILL.md format (YAML frontmatter + markdown instructions) that Claude Code, and increasingly other agent tools, read directly.
--- name: cache-strategy-advisor description: Design or review a caching strategy for a specific read path -- choice of TTL vs. explicit invalidation, cache key design, and staleness tolerance -- with invalidation correctness as the primary design constraint, not an afterthought. Use when adding caching or reviewing cache-related bugs. --- # Cache Strategy Advisor "Cache invalidation is hard" because it's usually designed last. Design it first. ## Questions to answer before choosing a strategy 1. **Staleness tolerance**: how stale can this data be before it's actually wrong for the use case? A dashboard metric tolerates minutes; an account balance does not. 2. **Invalidation trigger**: does the underlying data change on a known event (a write path you control), or unpredictably (external system)? If it's a write path you control, prefer explicit invalidation (invalidate/update the cache entry when the write happens) over a pure TTL guess. 3. **Cache key design**: does the key capture every dimension the cached value actually depends on? A cache key missing a dimension (e.g. caching by user ID but the response also depends on locale) serves wrong data to some users, silently. 4. **Stampede risk**: when a hot key expires, do many concurrent requests all miss at once and hammer the underlying source? Consider request coalescing or staggered TTLs for hot keys. 5. **Failure mode**: if the cache is unavailable, does the system degrade to the source of truth, or does it break? Prefer a design that fails open to correctness (fetch from source) over failing to stale/wrong data. ## Output Recommended strategy (TTL value + explicit invalidation on which write paths), cache key design, and an explicit answer to the stampede and cache-unavailable questions above.
Installing it elsewhere
The frontmatter/body split above is Claude Code's convention. Here's how to carry the same instructions into other tools:
Save the file below verbatim (frontmatter included) at that path, project-local or in ~/.claude/skills/ for a user-level skill. Claude Code loads the name/description pair to decide when to pull it in, or you invoke it directly as /cache-strategy-advisor.
Convert the YAML frontmatter to Cursor's rule format (description, globs, alwaysApply: false) and keep the markdown body as the rule content. Cursor surfaces it by description match, same idea as Claude Code's auto-load.
Codex CLI (and increasingly other agentic CLIs) read AGENTS.md at the repo root as always-on instructions. Paste the markdown body under a heading like ## {title}; for GitHub Copilot's coding agent, the equivalent file is .github/copilot-instructions.md.
Append the markdown body to .windsurfrules at the repo root. Windsurf treats the whole file as always-on context, so keep only the instructions you want applied on every request.
- Choosing a TTL by guessing instead of by actual staleness tolerance for the specific use case.
- A cache key that omits a dimension the response actually varies by, silently serving wrong data to a subset of users.
- No plan for cache-unavailable failure mode, so a cache outage becomes a full outage instead of degraded-but-correct behavior.