patternjavascriptModerate
Cache Tagging and Targeted Invalidation
Viewed 0 times
cache tagcache invalidationsurrogate keytag invalidationcontent relationship
Problem
After updating a product, you need to invalidate all cached pages that mention that product (product page, category page, search results, homepage featured items). Invalidating by URL requires knowing every affected URL.
Solution
Tag each cached item with logical labels at write time (e.g., product:123, category:electronics). On update, invalidate all items with the relevant tag in a single operation. Supported by Fastly, Cloudflare, Varnish (xkey), and application-level caches.
Why
Tag-based invalidation scales to complex content relationships. You invalidate by what changed, not by guessing which URLs are affected.
Gotchas
- Application-level cache tags require you to store a tag-to-keys mapping (e.g., a Redis Set per tag). Maintaining this mapping adds write overhead.
- Tag invalidation in distributed caches is eventually consistent — there is a window where some nodes still serve stale content.
- Over-tagging (attaching many tags per item) makes invalidation queries expensive.
Code Snippets
Redis-based cache tag invalidation
// On write: register key under each tag
async function setCachedWithTags(key, value, tags, ttl) {
await redis.set(key, JSON.stringify(value), 'EX', ttl);
for (const tag of tags) {
await redis.sadd(`tag:${tag}`, key);
}
}
// On update: invalidate all keys for a tag
async function invalidateTag(tag) {
const keys = await redis.smembers(`tag:${tag}`);
if (keys.length) await redis.del(...keys);
await redis.del(`tag:${tag}`);
}Revisions (0)
No revisions yet.