cache-invalidation
Cache invalidation — TTL, event-driven, cache-aside, write-through, SWR, tag purge
Best use case
cache-invalidation is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Cache invalidation — TTL, event-driven, cache-aside, write-through, SWR, tag purge
Teams using cache-invalidation should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/cache-invalidation/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How cache-invalidation Compares
| Feature / Agent | cache-invalidation | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Cache invalidation — TTL, event-driven, cache-aside, write-through, SWR, tag purge
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Cache Invalidation
## Overview
Cache invalidation is the process of removing or updating stale cached data when the underlying source of truth changes. It is famously one of the two hard problems in computer science. The goal is to balance freshness (serving current data) against performance (avoiding unnecessary origin fetches).
## When to Use
- Any system with a caching layer (Redis, CDN, in-memory, browser)
- APIs where data freshness requirements vary by endpoint
- E-commerce catalogs, CMS content, user profiles — data that changes but not on every request
- Multi-tier caches (browser -> CDN -> app cache -> database)
## Key Patterns
### Cache-Aside (Lazy Loading)
Application checks cache first; on miss, reads from DB and populates cache.
```typescript
async function getProduct(id: string): Promise<Product> {
const cacheKey = `product:${id}`;
const cached = await redis.get(cacheKey);
if (cached) return JSON.parse(cached);
const product = await db.query('SELECT * FROM products WHERE id = $1', [id]);
await redis.setex(cacheKey, 3600, JSON.stringify(product)); // 1h TTL
return product;
}
async function updateProduct(id: string, data: Partial<Product>) {
await db.query('UPDATE products SET ... WHERE id = $1', [id]);
await redis.del(`product:${id}`); // invalidate — next read repopulates
}
```
### Write-Through
Write to cache and DB simultaneously. Cache is always fresh but writes are slower.
```typescript
async function updateProduct(id: string, data: Partial<Product>) {
const updated = await db.query(
'UPDATE products SET ... WHERE id = $1 RETURNING *', [id]
);
await redis.setex(`product:${id}`, 3600, JSON.stringify(updated));
return updated;
}
```
### Event-Driven Invalidation
Decouple invalidation from the write path using events.
```typescript
// Publisher (in the write service)
await db.query('UPDATE products SET price = $1 WHERE id = $2', [newPrice, id]);
await eventBus.publish('product.updated', { id, fields: ['price'] });
// Subscriber (cache invalidation worker)
eventBus.subscribe('product.updated', async (event) => {
await redis.del(`product:${event.id}`);
await cdn.purgeTag(`product-${event.id}`);
});
```
### Tag-Based Purging (CDN / Vercel)
```typescript
// Set tags when caching
// Next.js revalidateTag example
import { revalidateTag } from 'next/cache';
// In a fetch call
fetch('https://api.example.com/products', {
next: { tags: ['products', `category-${categoryId}`] },
});
// On mutation — purge all caches with this tag
export async function updateCategory(id: string) {
await db.updateCategory(id);
revalidateTag(`category-${id}`);
}
```
### Stale-While-Revalidate (SWR)
Serve stale data immediately while refreshing in the background.
```typescript
// HTTP header approach
// Cache-Control: public, max-age=60, stale-while-revalidate=300
// Application-level SWR
async function getWithSWR<T>(key: string, fetcher: () => Promise<T>, ttl: number, swrWindow: number) {
const entry = await redis.hgetall(`swr:${key}`);
if (entry.data) {
const age = Date.now() - Number(entry.timestamp);
if (age < ttl * 1000) return JSON.parse(entry.data); // fresh
if (age < (ttl + swrWindow) * 1000) {
// stale but within SWR window — return stale, refresh async
refreshInBackground(key, fetcher, ttl);
return JSON.parse(entry.data);
}
}
// Cache miss or expired beyond SWR window
const fresh = await fetcher();
await redis.hset(`swr:${key}`, { data: JSON.stringify(fresh), timestamp: Date.now() });
return fresh;
}
```
## Pitfalls
- **Delete vs. update race**: Two concurrent writes can leave stale data. Prefer delete-on-write (cache-aside) over set-on-write unless you use versioning.
- **Thundering herd**: When a popular key expires, hundreds of requests hit the DB simultaneously. Use request coalescing or a lock to let one request repopulate.
- **Multi-layer inconsistency**: Browser cache, CDN, and app cache can all hold different versions. Set consistent TTLs and use `Vary` headers correctly.
- **Forgetting related keys**: Updating a product may require invalidating the product key, the category listing, search results, and recommendation caches. Use tag-based invalidation to group related entries.
- **TTL = 0 is not invalidation**: Zero TTL means "always revalidate," not "never cache." Understand the difference between no-cache and no-store.Related Skills
ultrathink
UltraThink Workflow OS — 4-layer skill mesh with persistent memory and privacy hooks for complex engineering tasks. Routes prompts through intent detection to activate the right domain skills automatically.
ultrathink_review
Multi-pass code review powered by UltraThink's quality gate — checks correctness, security (OWASP), performance, readability, and project conventions in a single structured pass.
ultrathink_memory
Persistent memory system for UltraThink — search, save, and recall project context, decisions, and patterns across sessions using Postgres-backed fuzzy search with synonym expansion.
ui-design
Comprehensive UI design system: 230+ font pairings, 48 themes, 65 design systems, 23 design languages, 30 UX laws, 14 color systems, Swiss grid, Gestalt principles, Pencil.dev workflow. Inherits ui-ux-pro-max (99 UX rules) + impeccable-frontend-design (anti-AI-slop). Triggers on any design, UI, layout, typography, color, theme, or styling task.
Zod
> TypeScript-first schema validation with static type inference.
webinar-registration-page
Build a webinar or live event registration page as a self-contained HTML file with countdown timer, speaker bio, agenda, and registration form. Triggers on: "build a webinar registration page", "create a webinar sign-up page", "event registration landing page", "live training registration page", "workshop sign-up page", "create a webinar page", "build an event page", "free webinar landing page", "live demo registration page", "online event page", "create a registration page for my webinar", "build a training event page".
webhooks
Webhook design patterns — delivery, retry with exponential backoff, HMAC signature verification, payload validation, idempotency keys
web-workers
Offload heavy computation from the main thread using Web Workers, SharedWorkers, and Comlink — structured messaging, transferable objects, and off-main-thread architecture patterns
web-vitals
Core Web Vitals monitoring (LCP, FID, CLS, INP, TTFB), measurement with web-vitals library, reporting to analytics, and optimization strategies for Next.js
web-components
Native Web Components, custom elements API, Shadow DOM, HTML templates, slots, lifecycle callbacks, and framework-agnostic design patterns
wasm
WebAssembly integration — Rust to WASM with wasm-pack/wasm-bindgen, WASI, browser usage, server-side WASM, and performance considerations
vue
Vue 3 Composition API, Nuxt patterns, reactivity system, component architecture, and production development practices