---
title: "Put a format version in every cache key · Agent Wranglers"
url: https://agentwranglers.se/playbook/scaling/caching/versioned-cache-keys
updated: 2026-10-21
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Put a format version in every cache key

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Caching](https://agentwranglers.se/playbook/scaling/caching.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers). Updated 2026-10-21.

- ID: SCL-12
- Level: Recommended
- Chapter: [Caching](https://agentwranglers.se/playbook/scaling/caching)
- Rule: Build each server cache key from a prefix, the data's format version and every input that changes the value. Add the tenant or user for private data.
- How: When a deploy changes the shape of a cached object, old copies still sit in the cache. The new code then reads a shape it does not expect, and a rollback reads the new one. Raise the version with each change of shape, and old keys expire on their own. Hash free text, such as a search term, so one key cannot collide with another. The same rule for data cached in the browser is [Key cached data by every input](https://agentwranglers.se/playbook/app-ui/client-and-server-state/complete-cache-keys).
- Check: Each key builder includes its version constant. A test fills the cache with entries of the old version, raises the version and reads again. It gets a miss, not a parse error.

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### JavaScript example

```js
import { createHash } from 'node:crypto';

const PRODUCT_CACHE_VERSION = 3;
const hash = text => createHash('sha256').update(text).digest('hex').slice(0, 16);

export const productKey = (tenantId, productId) => `product:v${PRODUCT_CACHE_VERSION}:${tenantId}:${productId}`;
export const searchKey = (tenantId, term) => `search:v${PRODUCT_CACHE_VERSION}:${tenantId}:${hash(term)}`;
```

### Python example

```python
import hashlib

PRODUCT_CACHE_VERSION = 3

def _hash(text: str) -> str:
    return hashlib.sha256(text.encode()).hexdigest()[:16]

def product_key(tenant_id: str, product_id: str) -> str:
    return f"product:v{PRODUCT_CACHE_VERSION}:{tenant_id}:{product_id}"

def search_key(tenant_id: str, term: str) -> str:
    return f"search:v{PRODUCT_CACHE_VERSION}:{tenant_id}:{_hash(term)}"
```

## Related rules

- [Key cached data by every input](https://agentwranglers.se/playbook/app-ui/client-and-server-state/complete-cache-keys) in App interface

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/scaling/caching/versioned-cache-keys">Agent Wranglers scaling playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Cache what is read often and costly to build](https://agentwranglers.se/playbook/scaling/caching/cache-hot-reads)
- Next: [Let one caller rebuild an expired entry](https://agentwranglers.se/playbook/scaling/caching/stampede-protection)
- [Caching](https://agentwranglers.se/playbook/scaling/caching)
