Learn
Lesson · Caching and Hit Rates · Where caches fail

TTL and Staleness

A TTL is a staleness budget, and the budget has a price. With updates every U seconds and a TTL of T, the expected fraction of time the cached copy is out of date is piecewise in T — T/(2U) below the update interval and 1 − U/(2T) above it. Halving T halves the staleness and doubles the misses, and the second half of that sentence is the one that gets left out.

stale fraction T/(2U) for T ≤ U 1 − U/(2T) for T ≥ U both give 1/2 at T = U miss rate = 1/(λ_key·T) one miss per key per TTL U = 60 s, T = 10 s, 5 reads/s: stale 1/12 = 8.33%, miss 1/50 = 2.00%
A piecewise staleness, and the misses a short TTL buys

Core ideas

What this lesson establishes

A model with two branches and two assumptions. The branches are easy; the assumptions are the reason the lab runs a timeline beside the formula.

1

A TTL does not keep data fresh — it bounds how stale it gets

A cached copy written at time 0 and held for T seconds is correct until the source changes and wrong from then until the window ends. The TTL never prevents that; it caps its duration at T. “We cache for sixty seconds” and “we serve data up to sixty seconds wrong” are the same sentence.

2

The stale fraction is piecewise in T

With updates every U and a uniform refresh phase, the expected stale fraction is T/(2U) while T ≤ U and 1 − U/(2T) once T ≥ U. The two branches agree at T = U, where both give 1/2. Below the update interval staleness is linear in the TTL; above it, it climbs toward 1 and never reaches it.

3

A shorter TTL is bought with misses

A key read λ_key times a second and expiring every T seconds misses once per window, so its miss rate is 1/(λ_key·T) — and 1 once the TTL is shorter than the gap between reads. At five reads a second and T = 10 s that is 1/50 = 2.00%. Halve T and it becomes 1/25 = 4.00%: half the staleness, twice the backend traffic.

The material

The staleness a TTL admits, and the misses a short one costs

Where the piecewise formula comes from, what it assumes, and why the lab runs a timeline next to it.

Definition · TTL and staleness

A cache entry written at time t with a time to live T is served until t + T and then discarded. If the underlying value changes at some time inside that window, the entry is stale from the change until the window ends. The stale fraction is the expected proportion of the window during which the entry is stale.

This is a staleness measured in time, not in reads. Weighting by reads gives the same answer when reads are spread evenly through the window, which is the case this lesson computes.

Two assumptions make the formula possible and both are visible on the page rather than buried. The first is that updates are periodic, every U seconds. The second is that the phase between the refresh clock and the update clock is uniform — the refresh lands at a time unrelated to the updates. Neither is true of a real system, and the lab lets you fix the phase and watch a single run disagree with the average.

Where the two branches come from

Let G be the time from the start of a refresh window to the next update, uniform on [0, U). The entry is fresh until that update and stale for the remainder of the window, so the stale time is max(0, T − G) — the piecewise function of Algebra, and the expected value of Discrete Mathematics applied to it.

stale time in one window = max(0, T − G), G uniform on [0, U) T ≤ U: E[max(0, T − G)] = T²/(2U) fraction = T²/(2U) ÷ T = T/(2U) T ≥ U: an update always lands in the window, so stale time = T − G E = T − U/2, fraction = 1 − U/(2T) at T = U both give 1/2
Example · A one-minute update, a ten-second TTL

U = 60 s, T = 10 s. Since T ≤ U the stale fraction is T/(2U) = 10/120 = 1/12 = 8.33%. Stretch the TTL to 30 s and it becomes 1/4 = 25.00%; to 60 s and it is 1/2 = 50.00%; to 120 s and the other branch gives 3/4 = 75.00%. A TTL twice the update interval means three quarters of the time you are serving something wrong.

What the other direction costs

So shorten the TTL. Staleness falls linearly — and every key now expires more often, so it misses more often. A key read λ_key times a second expires once every T seconds, and exactly one of the λ_key·T reads in that window pays for the refill, giving a miss rate of 1/(λ_key·T). Once λ_key·T ≤ 1 the key expires between reads and every read is a miss.

Example · The trade, at five reads a second

λ_key = 5. At T = 10 s the stale fraction is 1/12 and the miss rate 1/50 = 2.00%. At T = 1 s the stale fraction falls to 1/120 = 0.83% and the miss rate rises to 1/5 = 20.00% — a tenth of the staleness for ten times the backend reads. At T = 240 s the stale fraction is 7/8 = 87.50% and the miss rate is 1/1200 = 0.08%.

Both ends of that trade are a choice about what the system is for. A price display can be a minute wrong and must not melt the pricing service; a permission check can be nothing wrong and is read rarely enough that a short TTL costs little. The formula does not decide; it prices both options in the same units so the decision is not made by whoever spoke last.

Why the lab runs a timeline beside the formula

T/(2U) is an expectation over the phase, not a prediction about a particular run. Fix the phase at 30% of U with U = 60 s and T = 10 s and the run actually measures 1/30 = 3.33% stale against a formula that says 1/12 = 8.33%; averaged over twenty-four phases it lands back on 8.33% exactly. Neither number is wrong. They answer different questions.

That is the honest way to use this: as a sensitivity rather than a forecast. It tells you that doubling the TTL roughly doubles the staleness while T ≤ U, and that is a shape you can rely on even when the update process is not periodic at all. What it will not give you is the stale fraction your system had last Tuesday, and a model whose assumptions are on the page is one you can tell that about.

Interactive

TTL and staleness

What a TTL costs in stale reads, and what a shorter one costs in misses

A TTL is a staleness budgetT/(2U) below U, 1 − U/(2T) above it — and a timeline that runs
freshstalean updatea refresh

Method

Pricing a TTL

Both numbers, always. A TTL argument with only one of them in it is an argument about nothing.

1

Find the update interval U

How often does the underlying value actually change? Not how often it could — how often it does. If the answer is “rarely, and then suddenly”, the periodic model is the wrong one and the TTL should be paired with explicit invalidation.

2

Pick the branch and compute the stale fraction

T ≤ U gives T/(2U); T ≥ U gives 1 − U/(2T). Check the branch before substituting: at T = 2U the wrong branch gives 1 and the right one gives 3/4, and the error is invisible in the answer.

3

Compute the miss rate the TTL implies

1/(λ_key·T), for the per-key read rate. This is the number that turns a staleness decision into a capacity decision, and it is the one that gets omitted.

4

State both, and say what the formula assumes

“A ten-second TTL means about eight per cent of reads see data up to ten seconds old, and two per cent of reads reach the database, assuming the value changes about once a minute.” Every clause in that sentence is load-bearing.

Staleness, TTLs and their price

Score 0 / 0

U = 60 s, T = 10 s, 5 reads a second

One branch check, one substitution, one division — and then the same key at four other TTLs, because the point is the shape.

U = 60 s (the value changes once a minute), λ_key = 5 reads/s T = 10 s. T ≤ U, so the branch is T/(2U): stale = 10/(2·60) = 10/120 = 1/12 = 8.33% miss = 1/(λ_key·T) = 1/(5·10) = 1/50 = 2.00% the same key at other TTLs: T branch stale miss rate 1 s T/(2U) 1/120 = 0.83% 1/5 = 20.00% 15 s T/(2U) 1/8 = 12.50% 1/75 = 1.33% 30 s T/(2U) 1/4 = 25.00% 1/150 = 0.67% 60 s T/(2U) 1/2 = 50.00% 1/300 = 0.33% 120 s 1 − U/(2T) 3/4 = 75.00% 1/600 = 0.17% 240 s 1 − U/(2T) 7/8 = 87.50% 1/1200 = 0.08% 10 s → 1 s: staleness ÷ 10, backend reads × 10

The last line is the lesson. Every factor of ten you take off the staleness you put back on the backend, exactly, and there is no TTL at which both numbers are small unless the key is read very often relative to how often it changes.

For a faded rehearsal, take a key that changes every 10 s and is read 200 times a second. The supplied first move is that a 60 s TTL is past the update interval, so the branch is 1 − U/(2T); compute the stale fraction and the miss rate there, then find a TTL whose stale fraction is under 10% and say what its miss rate is. Report which of the two numbers this key can afford.

In the lab, set the phase control to 30% and compare the run against the formula: 1/30 measured against 1/12 predicted, with the twenty-four-phase average landing back on the formula. Then move the phase and watch how far a single run can sit from the number you would have quoted.

Common mistakes

1
Believing a shorter TTL fixes staleness for freeIt does not fix it — T/(2U) is zero only at T = 0 — and it is not free. Going from T = 10 s to T = 1 s at five reads a second takes the stale fraction from 1/12 to 1/120 and the miss rate from 1/50 to 1/5, which is ten times the backend load. Quote both numbers or you have not made an argument.
2
Using the wrong branchAt T = 2U the T/(2U) branch returns exactly 1, which looks like a sensible answer for a very long TTL and is wrong: the right branch gives 3/4. Compare T with U before substituting, every time. The branches meet at T = U, where both give 1/2.
3
Reading the formula as a prediction about a particular runIt is an expectation over the phase between the update clock and the refresh clock. With that phase fixed at 30% of U, a run at U = 60 s, T = 10 s measures 1/30 rather than 1/12. Use the formula to compare TTLs, not to report what last week’s staleness was.

Check your understanding

✓
Finish when a TTL proposal without a miss rate attached looks incomplete to you.

You should be able to choose the correct branch, compute the stale fraction and the implied miss rate for a TTL, state the two assumptions the formula rests on, and describe the trade between the two numbers as a factor rather than as a feeling.

Note: A TTL sets staleness against backend load on average. The moment it actually expires is not an average: a popular key going cold lets everything that arrives in the next few milliseconds through at once, and “Cache Stampedes” computes how many that is.

Kept in this browser only, for you. Nothing is sent anywhere and nothing checks it. Carry it to another device.

Feedback and recommendations

Something to change about this lesson? Write it down, tick it off when it is handled, and export the list when you want to act on it. Kept in this browser only: nothing is sent anywhere, and nobody is notified.

No recommendations yet for this lesson.