TTL Is Set in Three Places
The TTL of one file is set in three places: bucket metadata, the LB cache, and the CDN rule. It can only go down on the way, and a blank in IaC means default.
One place does not decide the TTL of a file. Three layers each have a setting. The TTL passes from storage to the client and can only go down on the way.
I thought TTL was set only on the CDN. When I dug in, I found three places on the path that decide it.
The Setting at Each Layer
| Layer | Setting | Our value |
|---|---|---|
| ① Bucket | Cache-Control metadata on the object | Not set at upload, so the bucket returns public, max-age=3600 |
| ② LB cache | cache mode | Cache all static files |
| default TTL / client TTL cap / max TTL | 3600 / 3600 / 86400 | |
| stale-while-revalidate time | 86400 (Stale-While-Revalidate: Serve Old First, Refresh in the Background) | |
| ③ Akamai | caching behavior | Obey Cache-Control and Expires, default 30 days |
- In the “cache all static files” mode, the client TTL cap is the upper limit of the
max-agethat the LB cache sends out. - So even if I set 30 days at upload, a file on the proxy route reaches Akamai with at most 3600 seconds.
- “Can only go down” holds only if Akamai obeys the
max-ageit receives. If Akamai uses a fixed TTL, it sits closest to the client and can override the values behind it (Cache Freshness: Fresh, Stale, and 304). - The LB cache also rewrites this header: the bucket returns
public, max-age=3600, and after the LB cache it becomespublic,max-age=3600.
No Written Setting Does Not Mean No Setting
We manage config with IaC (Infrastructure as Code). The LB cache rules were not written there, so I thought it had no rules. But when the cache is on, it always has a full set of defaults. I asked the cloud platform directly and read the real values.
A blank in IaC does not mean “none”. It means “default”.
Sources: RFC 9111: HTTP Caching
Related: Cache Freshness: Fresh, Stale, and 304, Cache Headers: Who Sets, Who Reads, The Path of One Request, Stale-While-Revalidate: Serve Old First, Refresh in the Background, What I Learned: A Cache Is a Chain, Not a Box. Or go back to the series overview.