Type to search pages and rules.

Browse pages

Caching

Caching trades freshness and invalidation work for lower latency or source load.

Markdown13 provisions

Intent#

Caching trades freshness and invalidation work for lower latency or source load. This extension requires measurement, a named staleness contract, and a recovery path.

Activation#

Activation scope: local.

Applicable specification kinds: use-case.

The consumer enables cache after traces or load tests identify a repeated expensive read and the use case can state acceptable staleness. Future traffic alone does not activate it.

Baseline relationship#

This extension replaces no baseline provision. A provider package needs a project decision and manifest pin.

This extension switches on limit. The accepted staleness and the expiry of each cache are Limit records.

Standards#

Record measured cache need#

ruleguidance

Requirement A cache proposal MUST record its observed query, representative load, latency, source cost, target, accepted staleness as a Limit record, owner, status, decider, and decide-by.

Rationale The record makes the cache's freshness and operating-cost trade-off reviewable.

litespec/ext/cache#record-measured-cache-need

Remove unjustified caches#

ruleguidance

Requirement A cache owner MUST remove a cache when measurements do not justify its operating cost.

Rationale A cache creates invalidation, capacity, and recovery work that needs continuing value.

litespec/ext/cache#remove-unjustified-caches

Compose cache keys from result inputs#

ruleguidance

Requirement A cache key MUST include its data-shape version, every result-affecting input, and applicable tenant or actor partition.

Rationale The key separates results that have different shapes, callers, or input values.

Example post-summary:v2:tenant-42:post-17 identifies a versioned, tenant-scoped result.

litespec/ext/cache#compose-cache-keys-from-result-inputs

Exclude unsafe cache key material#

ruleguidance

Requirement A cache key MUST NOT contain a secret, unbounded raw input, or personal data that is not already a hash.

Rationale Keys appear in diagnostics, metrics, and provider administration tools. That copies the value into a store no one classified. An email address in a key is a personal-data record in the cache provider's key space. It sits outside every retention and erasure path the project defined. Data minimization applies to an identifier as much as to a field.

Example A per-account cache key carries the account's opaque identifier. A key that carried the address instead is replaced by a hash of it, and the entry is bound to the account that owns it.

litespec/ext/cache#exclude-unsafe-cache-key-material

Define cache invalidation#

ruleguidance

Requirement A cached value MUST define expiry as a Limit record, invalidating write events, an invalidation owner, and behavior after invalidation failure.

Rationale An explicit contract makes stale data behavior visible before implementation.

litespec/ext/cache#define-cache-invalidation

Record a manual cache invalidation#

ruleguidance

Requirement A manual invalidation MUST produce a record naming actor, scope, and reason, as an audit record in its category when the audit extension is selected.

Rationale A manual clear changes what every later reader sees and leaves no trace in the data itself. Investigating a stale-read report afterward means knowing whether someone already cleared the entry. Article 30 of the GDPR treats an administrative action over personal data as processing that has a record.

Example A command that clears one tenant's cached price list records the tenant, the operator, and the incident it was run for.

litespec/ext/cache#record-a-manual-cache-invalidation

Prefer bounded staleness#

ruleguidance

Requirement A cache owner SHOULD use a short expiry when precise invalidation costs more than recomputation.

Deviation: A measured staleness and operating-cost decision permits a longer expiry.

Rationale Short expiry limits stale data when invalidation precision is not economical.

litespec/ext/cache#prefer-bounded-staleness

Keep source data authoritative#

ruleguidance

Requirement A cache implementation MUST keep required business data authoritative in its source of record.

Rationale A cache stores a derived copy rather than the sole required business record.

litespec/ext/cache#keep-source-data-authoritative

Define cache outage behavior#

ruleguidance

Requirement A cache outage MUST use the source when capacity permits or return a documented degraded response.

Rationale Callers need predictable behavior when cache infrastructure is unavailable.

litespec/ext/cache#define-cache-outage-behavior

Emit a signal for each degraded cache path#

ruleguidance

Requirement A cache path MUST emit a metric distinguishing a cache miss, a cache error, and a degraded response.

Rationale A fallback that works is invisible. An outage runs until someone notices the source load instead. The three cases need different responses: a miss is normal, an error is an infrastructure fault, and a degraded response is a product behavior change. One counter for all three answers none of them.

Example The metric carries the cache name and the outcome, following the OpenTelemetry semantic conventions for the client it wraps.

litespec/ext/cache#emit-a-signal-for-each-degraded-cache-path

Bound cache refresh work#

ruleguidance

Requirement A cache implementation MUST bound simultaneous refresh work when concurrent misses could overload its source.

Rationale Bounded concurrency, request coalescing, and jittered expiry are valid techniques.

Example One request refreshes a key while concurrent callers await the same bounded work.

litespec/ext/cache#bound-cache-refresh-work

Avoid unbounded key locks#

ruleguidance

Requirement A cache implementation MUST NOT create an unbounded per-key lock inventory.

Rationale Unbounded lock state can exhaust memory under untrusted or high-cardinality keys.

litespec/ext/cache#avoid-unbounded-key-locks

Conventions#

Place cache access at an outer boundary#

conventionguidance

Default Place cache access in Infrastructure or a frontend data boundary.

Replacement A consumer records a departure from this default as an Exception record with reason and review date.

Rationale Application owns any external cache port required by a use case. Domain code has no cache dependency.

litespec/ext/cache#place-cache-access-at-an-outer-boundary

Dependencies#

This extension selects no provider package.

Verification#

IDMarkEvidence
litespec/ext/cache#record-measured-cache-needguidanceDoes the proposal record the query, load, latency, cost, target, staleness, and ownership?
litespec/ext/cache#remove-unjustified-cachesguidanceDoes a cache leave when measurements do not justify its cost?
litespec/ext/cache#compose-cache-keys-from-result-inputsguidanceDoes each key separate version, result inputs, and tenant or actor partition?
litespec/ext/cache#exclude-unsafe-cache-key-materialguidanceIs every key free of secrets, unbounded input, and unhashed personal data?
litespec/ext/cache#define-cache-invalidationguidanceDoes each cached value define expiry, events, an owner, and failure behavior?
litespec/ext/cache#record-a-manual-cache-invalidationguidanceDoes a manual clear write a record naming the actor, the scope, and the reason?
litespec/ext/cache#prefer-bounded-stalenessguidanceDoes the expiry stay short unless a measured decision permits longer?
litespec/ext/cache#keep-source-data-authoritativeguidanceIs the required business data authoritative in its source of record?
litespec/ext/cache#define-cache-outage-behaviorguidanceDoes an outage use the source or return the documented degraded response?
litespec/ext/cache#emit-a-signal-for-each-degraded-cache-pathguidanceDo a miss, an error, and a degraded response each increment their own metric?
litespec/ext/cache#bound-cache-refresh-workguidanceDoes concurrent-miss refresh stay bounded and protect the source?
litespec/ext/cache#avoid-unbounded-key-locksguidanceDoes lock state stay bounded under high-cardinality keys?
litespec/ext/cache#place-cache-access-at-an-outer-boundaryguidanceIs cache access outside Domain, or is there a recorded Exception?