# Invalidation Strategies — Caching Strategies & CDN Design

Source: https://www.skillbyai.com/en/caching-strategies/i-strategies

> Invalidate with deletes, versioned keys, tags and change data capture.

## Ways to make caches forget

**Delete on write**: after committing a change, delete the affected keys; the next read reloads. Prefer deleting to updating the cached value, which risks writing an older value over a newer one. **Versioned keys**: include a version number or content hash in the key (`profile:42:v17`); a change increments the version stored in the database, readers build keys from the current version, and old entries simply age out. This is also how **fingerprinted static assets** work (`app.3f9a1c.js`). **Tag-based invalidation**: label entries with the entities they depend on and invalidate by tag; CDNs offer this as cache tags or surrogate keys. **Event-driven invalidation**: services publish change events and cache owners invalidate on receipt. **Change data capture (CDC)**: a process reads the database's change log (for example with Debezium) and invalidates keys for every committed change, catching even writes that bypass application code.

## Invalidation from a change data capture stream

Every committed row change triggers invalidation, whichever code path made it.

```python
def on_change_event(event):
    """Called for each committed row change read from the database's change log."""
    table = event["source"]["table"]
    row = event["after"] or event["before"]           # after is empty for deletes

    if table == "products":
        redis.delete(f"product:v2:{row['id']}")
        cdn.purge_tags([f"product-{row['id']}", f"category-{row['category_id']}"])
    elif table == "prices":
        redis.delete(f"product:v2:{row['product_id']}")
        cdn.purge_tags([f"product-{row['product_id']}"])
```

## A library recall slip

When a book edition is corrected, the library sends recall slips to every branch holding a copy (invalidation by tag). Printing a new edition number on the cover (versioned keys) means branches can simply stop lending the old edition.

**Quiz:** Why is deleting a cache key on write usually safer than writing the new value into the cache?

- [ ] Deleting is faster in every cache
- [ ] Writing to caches is not allowed
- [ ] Deleting also updates the database
- [x] Concurrent writers could otherwise leave an older value in the cache last

*Answer:* Concurrent writers could otherwise leave an older value in the cache last. With concurrent updates, set operations can land out of order; deletes force a fresh reload.
