advanced24 min studyLesson 321 in Engineering

Cache keys are equivalence claims

Design canonical keys that preserve tenant, authorization, representation, and source-version boundaries.

On this page

What you’ll understand

  • Explain the correctness implication of sharing a cache key.
  • Distinguish safe canonicalization from collapsing meaningful request differences.
  • Account for representation and authorization context without storing raw credentials.

A cache key claims that requests mapped to it can safely reuse the same stored result under a defined freshness contract. A collision in that meaning can leak another tenant's data or return a different representation even when the hash function is perfect. Begin with the equivalence relation the application actually permits. Encoding and hashing come later, after identity, permissions, parameters, and version boundaries have been specified.

Define which results can be shared

List every input that can change the response: tenant identity, resource identity, selected fields, locale, format, feature configuration, and source version where relevant. Authorization needs particular care. A tenant-scoped key may still be too broad when users in that tenant have different visibility. Recheck permissions at the appropriate boundary and decide whether entries represent public, role-scoped, user-scoped, or permission-versioned data. A correct identifier does not make a previously authorized result safe after permissions change.

A raw bearer token is generally a poor cache-key component because it exposes a secret and fragments entries unnecessarily. Prefer a stable nonsecret authorization scope or a deliberate private-cache policy, while preserving the actual access-control decision. For HTTP shared caches, follow the protocol's Authorization and cache-control rules rather than implementing an informal application rule. Vary identifies relevant request-header dimensions, but does not automatically capture every application-specific tenant or permission distinction.

K(r1)=K(r2)⟹R(r1)≡CR(r2)K(r_1)=K(r_2)\Longrightarrow R(r_1)\equiv_{\mathcal C}R(r_2)
Requests sharing a key must have equivalent reusable responses under contract C, including access scope, representation, and freshness. This is a logical correctness condition, not a probabilistic guarantee supplied by hashing.↔ Scroll wide equations horizontally.

Canonicalization must preserve meaning

Sorting independent named parameters can make equivalent requests share a key, but repeated parameters, order-sensitive filters, Unicode normalization, case, and missing-versus-empty values may change meaning. Apply transformations only when the API contract establishes equivalence. Use a structured, unambiguous encoding, such as length-prefixed fields or a precisely specified serializer. Naive concatenation can make different tuples identical before hashing, which no stronger digest can repair. Test both equivalences and intentionally distinct near-collisions.

Namespace keys by schema or representation version so a deployment can change the stored shape without interpreting old bytes incorrectly. Bound key lengths and reject unsupported input combinations. A digest can compact a canonical encoding, but digest collision handling and operational debuggability still need a policy. Avoid logging sensitive canonical contents merely to debug hit rates. Store enough nonsecret metadata to identify the key schema and scope without recreating a credential or personal-data leak.

Nvariants≤∏j=1dvjN_{\rm variants}\leq\prod_{j=1}^{d}v_j
With d dimensions having at most vj permitted values, the product bounds the number of distinct combinations before invalid combinations are excluded. Counts are dimensionless; this is a cardinality budget, not a claim that every combination is requested or cacheable.↔ Scroll wide equations horizontally.

Test shared and separated cases deliberately

Create paired requests that should share a response and paired requests that must remain separate. Include tenants with overlapping resource identifiers, permission changes, locale differences, missing parameters, and repeated fields. Check the actual returned data and authorization result, not just generated strings. A warm-cache test matters because a cold request can consult the origin and conceal a flawed reuse decision. During a key-schema rollout, measure temporary duplicate storage and cold-origin load as well as correctness.

The cache lab demonstrates key identity only as a toy address trace. Reset and set both C=4, s=4; predict four distinct identifiers and twelve hits among the initial sixteen requests, then Step to add one hit. The fully associative empty-start LRU trace requests (i×s) mod 16 and caps at 4096 requests. It has no tenant, permission, or representation context. Its successful hits therefore cannot validate an application's equivalence relation; explain which extra key dimensions would make those reused values safe.

Count useful representation dimensions

A resource has 12 tenants,3 supported locales, and 2 response formats. Resource identifiers can repeat across tenants. Assume every combination is allowed and has different reusable bytes.

  1. For one identifier value, the tenant-locale-format combinations number 12×3×2=72. A key containing only the identifier incorrectly collapses all seventy-two possibilities.

  2. Adding tenant but omitting locale and format still merges six potentially different responses per tenant. A canonical tuple must preserve all three dimensions under the stated contract.

  3. If authorization differs within a tenant, even the 72-way partition may be insufficient. Add the appropriate nonsecret scope or private policy, and handle permission-version changes rather than embedding raw credentials.

The result

Cardinality follows the response contract. Fewer keys are not an optimization when they merge results that cannot safely be shared.

Explore the model

Interactive lab

Interactive lab · cache

A hit proves identity only within the toy

Reset and set C=4, s=4: predict four misses and twelve hits at t=0, then Step to add one hit. This capped 4096-request LRU address model has no authorization, tenants, canonicalization, or HTTP cache rules.

A hit proves identity only within the toyA fully associative LRU cache starts empty and requests address (i·s) mod 16. Hits move an address to the newest position; misses evict the oldest when full. Playback starts with 16 requests and adds two per second, capped at 4096 explicitly simulated requests. This toy stream is not a processor-cache benchmark. Current readings: Hits / requests: 0 / 16; Hit rate: 0%; Address-stream period: 16 addresses. All parameters are adjustable with the labeled controls below.Fully associative LRU cache after 16 deterministic requests: 0 hits and 16 misses.Most recent 16 requestsaddress = i × 3 mod 160M3M6M9M12M15M2M5M8M11M14M1M4M7M10M13MCurrent cache order · oldest → newest471013Latest address 13 · miss: inserted as newestToy address stream · period 16 · starts empty
Cached addressMiss / evictionMost recent request
Hits / requests
0 / 16
Hit rate
0%
Address-stream period
16 addresses
t = 0 s

A fully associative LRU cache starts empty and requests address (i·s) mod 16. Hits move an address to the newest position; misses evict the oldest when full. Playback starts with 16 requests and adds two per second, capped at 4096 explicitly simulated requests. This toy stream is not a processor-cache benchmark. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.

Look forKey equality is useful only when it preserves the real response and access-control contract.

Check your understanding

Two tenants use the same numeric document identifier but have different document contents. What key design is justified?

Try it yourself

A search API treats repeated sort fields as order-sensitive but treats the order of independent filter names as irrelevant. Which part may be sorted during canonicalization, and what test would expose an unsafe transformation?

Take a moment to make a prediction or work it out on paper. Open a hint when you need one.

Give me a hint

Canonicalization follows semantic equivalence rather than visual similarity of requests.

Compare with the solution

Sort independent filter-name entries only under the API's stated equivalence, preserving their values and multiplicity rules. Do not sort the ordered sort-field sequence. A paired warm-cache test with sort=[price, rating] versus sort=[rating, price] should preserve different results when the contract says their precedence differs. Also test different tenants to ensure canonicalization does not erase access boundaries.

Take it with you

  • Key sharing is a claim about safe response equivalence.
  • Canonicalization must preserve access scope and meaningful parameter differences.
  • Versioned schemas and warm-cache tests reveal reuse errors that hashing cannot fix.

Read further

Original sources and deeper explanations to follow at your own pace.

Optional progress, saved in this browser when available. Revisit any lesson at any time.

Lesson not marked complete.