Initial commit
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
# Cache Invalidation Patterns
|
||||
|
||||
## Event-Based: Invalidate on Data Changes
|
||||
|
||||
Use when: consistency critical, staleness unacceptable.
|
||||
|
||||
```typescript
|
||||
async function createPost(data: { title: string; content: string; authorId: string }) {
|
||||
const post = await prisma.post.create({ data });
|
||||
|
||||
await Promise.all([
|
||||
redis.del(`posts:author:${data.authorId}`),
|
||||
redis.del('posts:recent'),
|
||||
redis.del('posts:popular'),
|
||||
]);
|
||||
|
||||
return post;
|
||||
}
|
||||
```
|
||||
|
||||
## Time-Based: TTL-Driven Expiration
|
||||
|
||||
Use when: staleness acceptable for TTL duration, mutations infrequent.
|
||||
|
||||
```typescript
|
||||
async function getRecentPosts() {
|
||||
const cached = await redis.get('posts:recent');
|
||||
if (cached) return JSON.parse(cached);
|
||||
|
||||
const posts = await prisma.post.findMany({
|
||||
orderBy: { createdAt: 'desc' },
|
||||
take: 10,
|
||||
});
|
||||
|
||||
await redis.setex('posts:recent', 300, JSON.stringify(posts));
|
||||
return posts;
|
||||
}
|
||||
```
|
||||
|
||||
## Hybrid: TTL + Event-Based Invalidation
|
||||
|
||||
Use when: mutations trigger immediate invalidation, TTL provides safety net.
|
||||
|
||||
```typescript
|
||||
async function updatePost(postId: string, data: { title?: string }) {
|
||||
const post = await prisma.post.update({
|
||||
where: { id: postId },
|
||||
data,
|
||||
});
|
||||
await redis.del(`post:${postId}`);
|
||||
return post;
|
||||
}
|
||||
|
||||
async function getPost(postId: string) {
|
||||
const cached = await redis.get(`post:${postId}`);
|
||||
if (cached) return JSON.parse(cached);
|
||||
|
||||
const post = await prisma.post.findUnique({
|
||||
where: { id: postId },
|
||||
});
|
||||
if (post) await redis.setex(`post:${postId}`, 600, JSON.stringify(post));
|
||||
return post;
|
||||
}
|
||||
```
|
||||
|
||||
## Strategy Selection by Data Characteristics
|
||||
|
||||
| Characteristic | Approach |
|
||||
| ------------------------- | ------------------------------------------------------------------------------------------------------------ |
|
||||
| Changes >1/min | Avoid caching or use 5-30s TTL; consider real-time updates; event-based invalidation for consistency |
|
||||
| Changes rare (hours/days) | Use 5-60min TTL; event-based invalidation on mutations; warm cache on startup |
|
||||
| Read/write ratio >10:1 | Strong cache candidate; cache-aside pattern; warm popular data in background |
|
||||
| Read/write ratio <3:1 | Weak candidate; optimize queries instead; cache only if DB bottlenecked |
|
||||
| Consistency required | Short TTL + event-based invalidation; cache-through/write-behind patterns; add versioning for atomic updates |
|
||||
Reference in New Issue
Block a user