Cache-Control and TTL
Freshness is the heart of any cache: how long a stored response counts as current, and what happens when it goes stale. This article explains how the proxy cache decides freshness, how to tune it with size and TTL, how to invalidate entries, and how it falls back to your origin.
Freshness is the heart of any cache: how long a stored response counts as current, and what happens when it goes stale. This article explains how the proxy cache decides freshness, how to tune it with size and TTL, how to invalidate entries, and how it falls back to your origin.
The two TTLs
The proxy cache uses two related settings:
- Cache TTL (default 300 s) — how long a stored response is considered fresh. Within this window, requests are served straight from the cache.
- Storage TTL (optional, must be ≥ cache TTL) — how long the response is kept after it goes stale. A stale-but-stored entry can serve as a fallback if your container is briefly unreachable, avoiding a cold re-fetch.
For most APIs, a cache TTL of 60–600 s is the right range. Content that changes only a few times a day sits comfortably at 3600 s or more.
Honouring Cache-Control
By default the proxy cache honours Cache-Control, which means your container can override the platform's TTL on a per-response basis using standard headers:
Cache-Control: public, max-age=120This lets your application decide freshness response by response — cache a rarely changing page for an hour, mark a volatile one as short-lived, and so on. If you would rather the platform settings always win regardless of what your container sends, turn honouring off, and the configured cache TTL applies unconditionally.
Tuning size and TTL together
Size and TTL interact. A longer TTL keeps entries around longer, so more of them coexist and the cache needs more room; a larger cache holds a bigger working set and lifts the hit rate. A rough starting point for size:
working_set = avg_response_size_kb * unique_cacheable_urls
target_size = working_set * 1.5 # headroom for metadata and churnIf you cannot estimate it, start at a modest size, watch the hit rate after a day of real traffic, and resize. The full sizing walk-through, worked examples, and cache-key guidance live in Proxy caching; the Tuning the proxy cache post goes deeper on trade-offs.
Cache invalidation strategies
The most reliable way to control staleness is to let entries expire naturally — pick a TTL you can live with and accept that some callers see data up to one TTL old. Beyond that:
- Shorten the TTL for data that must stay fresher. This trades a lower hit rate for tighter freshness.
- Narrow or version the cache key. If a response depends on a query parameter or a header, include it in the key so different variants do not collide. Changing a versioned path (for example a build hash in the URL) sidesteps stale entries entirely, because new content lives at a new key.
- Keep the key narrow. Every dimension you add to the key multiplies the number of entries and dilutes the hit rate, so only vary on what genuinely changes the response.
Because the proxy cache keys on the request, precise, code-driven invalidation of individual items is better served by Memcached, where your application owns the keys and can delete one directly.
Origin fallback
The proxy cache is designed to fail safe. If the cache is unavailable, the platform forwards the request to your container origin transparently — a cache problem never turns into a request failure. And when storage TTL is set, a stale entry can stand in for a briefly unreachable origin, so a short blip upstream does not become an error for your callers.
Related
From the blog