ttl-selection
Choose a time-to-live duration that bounds the staleness window of cached values to a level
Files1
View on GitHubSKILL.mdsubagents/caching-strategy-advisor/skills/ttl-selection/SKILL.md
GitHubTTL Selection
Purpose
Choose a time-to-live duration that bounds the staleness window of cached values to a level the application can tolerate, while recognising that TTL expiry reduces but does not eliminate inconsistency (P004). When approximate freshness is sufficient — for example, social counters or slowly-changing configuration — TTL is the right consistency mechanism. When strong consistency is required — for example, financial balances or inventory counts — TTL alone is insufficient and the skill routes the caller to explicit invalidation or write-through instead.
When to use
- The application has stated a maximum acceptable staleness window and can tolerate reads that are slightly out of date within that window.
- The data changes occasionally or regularly but not on every access (dynamically-changing backing data is explicitly in scope per the source, h0105).
- Simpler consistency mechanisms are preferred over explicit invalidation, and the use case does not require that every read reflects the most recent write.
Do not use this skill when:
- Any stale read would cause a correctness, financial, or safety failure (P004
does_not_apply_when). Route tocache-invalidation-designfor explicit invalidation or write-through patterns instead. - The data is immutable or append-only (no inconsistency risk; TTL adds no benefit over a permanent entry).
Inputs
| Input | Required | Description |
|---|---|---|
| Maximum staleness tolerance | Yes | The longest period of stale data the caller's application can accept, expressed in concrete units (seconds, minutes, hours). |
| Consistency requirement | Yes | Whether strong consistency (every read reflects the latest write) or approximate freshness (bounded staleness) is required. |
| Data change frequency | Recommended | How often the backing data changes — informs whether the TTL will be hit frequently or rarely. |
| Deployment topology | Recommended | Single-node or geographically distributed / multi-node cache — affects whether cross-node propagation lag must be added to the TTL calculation. |
| Eviction policy in use | Optional | The configured maxmemory-policy — TTL-based per-key expiry is distinct from the eviction algorithm and both can be active simultaneously (P005). |
Procedure
Step 1: Gate on consistency requirement
Ask whether a stale read would cause a correctness, financial, or safety failure.
- If yes: do not proceed with TTL-only consistency. The root cause is that the backing data
changes without the cache being updated (c055, root cause 1), and the mitigation must be
explicit invalidation on write or write-through (P003). Redirect to the
cache-invalidation-designskill. Document the reason for the redirect. - If no (approximate freshness is acceptable): continue to Step 2.
Examples of approximate-freshness contexts (acceptable for TTL): social engagement counters, product catalogue entries, feature-flag configuration, recommendation lists.
Examples of strong-consistency contexts (not acceptable for TTL alone): financial account balances, inventory stock counts, access-control permissions.
Step 2: Identify the root cause of potential inconsistency
Classify which consistency failure mode applies (c055, P003):
- Root cause 2 — update propagation lag: The backing store changes and the cache is notified, but there is a delay before the cached value is updated (h0105). TTL bounds the window during which a stale value may be served.
- Root cause 3 — cross-node inconsistency: In geographically distributed or highly scaled caches, different nodes may temporarily hold different values while an update propagates (h0106, c059). TTL alone does not prevent inter-node divergence but does limit how long a single stale entry persists on any node.
If root cause 1 (underlying data changes with no cache update at all) is the dominant mode and no invalidation mechanism is in place, TTL is only a partial mitigation: stale entries will persist for up to one full TTL period after each change. If the update rate is high relative to the TTL, consider adding explicit invalidation on write (P003) alongside TTL as a safety net.
Step 3: Derive the TTL value from the acceptable staleness window
Set TTL to equal the maximum staleness the application can tolerate (c057). The TTL is a direct expression of that tolerance:
- A shorter TTL reduces the maximum staleness but increases the miss rate, driving more requests to the backing data source.
- A longer TTL reduces backing-source load but widens the window during which stale data may be served.
Concrete derivation approach:
- Obtain the caller's maximum staleness tolerance (e.g. "counters may be up to 60 seconds stale").
- Set TTL = that duration (e.g. 60 seconds).
- If the backing data changes on a known schedule (e.g. refreshed every 5 minutes), a TTL longer than the refresh period wastes nothing and reduces unnecessary misses; a TTL shorter than the refresh period is the more conservative choice.
Do not fabricate or assume a staleness tolerance. If the caller has not stated one, ask before proceeding.
Step 4: Adjust for cross-node propagation lag (distributed deployments)
If the cache is geographically distributed or uses replica nodes (c059, h0106):
- The time to propagate an update to all nodes is additional latency on top of any per-key expiry.
- The effective staleness window from a client's perspective is: TTL + worst-case propagation lag.
- Reduce the TTL by the estimated propagation lag so that the total staleness window stays within tolerance.
Example: if the tolerated staleness is 120 seconds and cross-region propagation typically takes 15 seconds, set TTL to 105 seconds or less.
For single-node deployments, propagation lag is zero and this adjustment is not required.
Step 5: Confirm TTL is a per-key setting, separate from eviction policy
TTL expiry is applied per key (via Redis EXPIRE or inline at write time). It is not the same
as the maxmemory-policy eviction algorithm (P005). Both mechanisms can be active at the same
time:
maxmemory-policy(e.g.volatile-lru,allkeys-lfu) determines which keys Redis removes when the cache is full.- Per-key TTL determines when a specific key becomes eligible for expiry regardless of memory pressure.
Ensure the caller understands the distinction so that enabling an eviction policy is not mistaken for having set TTL-based consistency, and vice versa.
Step 6: Document the TTL decision
Produce the output artifact described below, recording the rationale so the TTL is not adjusted later without revisiting the staleness-tolerance assumptions.
Output
A TTL recommendation containing all of the following:
- Recommended TTL value (explicit duration with units).
- Staleness window justification — the maximum staleness the TTL is designed to bound, with the tolerance stated by the caller.
- Consistency class — confirmation that approximate freshness is acceptable for this use case, or (if applicable) a redirect note explaining why TTL alone is insufficient and which alternative skill was invoked.
- Propagation-lag adjustment (if distributed topology) — the propagation-lag estimate and how it was deducted from the raw TTL.
- Eviction-policy note — a one-line statement that this TTL is per-key expiry and is
independent of any configured
maxmemory-policy.
References
principles/principles.yaml— P003 (consistency root causes), P004 (TTL inconsistency boundary rule), P005 (eviction policy selection).evidence/evidence-records.yaml— e026 (c055, h0103: three root causes), e027 (c057, h0105: TTL bounds staleness window), e028 (c058, h0105: TTL insufficient for financial data), e029 (c059, h0106: geo-distributed propagation lag).skills/cache-invalidation-design/SKILL.md— for explicit invalidation and write-through patterns when strong consistency is required.references/redis-maxmemory-policy-cheatsheet.md—volatile-ttland TTL-aware eviction policy options.
Provenance
Derived from principles P004 (primary), P003 (consistency root-cause classification), and P005 (TTL as eviction choice). Evidence records: e027 (c057, h0105), e028 (c058, h0105), e029 (c059, h0106), e026 (c055, h0103). Source: Atchison, "Caching at Scale With Redis" (2021), distillation-only rights — no verbatim quotation of source text.