A CDN’s edge cache is more of a "suggestion box" than a strict filing cabinet, and how well it plays along dictates your performance.
Let’s say you’re serving a popular image, logo.png, from your origin server at origin.example.com. A user in London requests it. The request hits your CDN’s London edge server.
GET /logo.png HTTP/1.1
Host: origin.example.com
User-Agent: Mozilla/5.0 ...
Accept: image/avif,image/webp,image/apng,image/*,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
...
The edge server checks its cache. If it has logo.png and it’s still "fresh" (based on cache-control headers), it serves it directly. This is a cache hit. If not, it asks your origin.example.com for the file – a cache miss. It then stores a copy and serves it to the London user. The next user in London requesting logo.png will likely get a hit.
The goal is to maximize these hits. High hit rates mean fewer requests hit your origin, reducing its load and your costs, and serving content faster to users.
Here’s how you make the edge server a better "suggestion box" keeper:
1. Cache-Control Headers: The CDN’s Rulebook
Your origin server tells the CDN (and browsers) how long to cache content. The most important headers are Cache-Control and Expires.
-
Cache-Control: public, max-age=31536000- Diagnosis: Check your origin server’s response headers for static assets like images, CSS, and JS. Use
curl -I https://origin.example.com/logo.png. - Fix: Set aggressive
max-agevalues for immutable assets.31536000(one year) is common for versioned files (e.g.,app.a1b2c3d4.js). For content that might change but infrequently,86400(one day) or3600(one hour) are good starting points. - Why it works: A long
max-agetells the CDN, "This file won’t change for a year, feel free to keep it around."
- Diagnosis: Check your origin server’s response headers for static assets like images, CSS, and JS. Use
-
Cache-Control: no-cache- Diagnosis: If you see
no-cacheon assets that should be cached, this is a problem. - Fix: Change
no-cachetopublic, max-age=...for cacheable assets.no-cachedoesn’t mean "don’t cache"; it means "revalidate with the origin before serving." This kills hit rates. - Why it works: By removing
no-cache, you allow the CDN to serve the cached version without always asking the origin, as long as themax-agehasn’t expired.
- Diagnosis: If you see
2. Vary Header: The Nuance of Content
The Vary header tells the CDN that the response depends on certain request headers. If a request header changes, the cached object might be invalid.
-
Vary: Accept-Encoding- Diagnosis: Check
curl -I https://origin.example.com/styles.css. If you seeVary: Accept-Encoding, it’s good for Gzip. If you seeVary: User-AgentorVary: Accept-Languageon static assets, it’s usually a mistake. - Fix: Remove
Varyheaders for static assets that don’t actually change based on those request headers. If yourstyles.cssis the same regardless ofUser-Agent, removeVary: User-Agent. - Why it works: A
Varyheader on a request header that doesn’t affect the response causes the CDN to treat identical resources as different for each variation, leading to cache misses.
- Diagnosis: Check
-
Vary: Accept-Encoding(when serving Gzipped content)- Diagnosis: This is generally good for assets that you compress.
- Fix: Ensure your CDN is configured to handle
Accept-Encodingcorrectly. Most CDNs automatically serve Gzipped content if the client supports it and the origin sendsContent-Encoding: gzipalong withVary: Accept-Encoding. - Why it works: This header tells the CDN to cache both the Gzipped and non-Gzipped versions separately, serving the appropriate one based on the client’s
Accept-Encodingheader.
3. Query String Parameters: The Traps
Query strings are often used for tracking, A/B testing, or cache-busting, but they can decimate cache hit rates if not managed.
-
https://example.com/script.js?v=1.2.3vs.https://example.com/script.js?v=1.2.4- Diagnosis: Observe your CDN’s analytics for cache hit rates. If they are surprisingly low for assets that appear static, check for query strings.
- Fix: Configure your CDN to ignore specific query string parameters for caching. For example, tell your CDN to ignore
utm_source,fbclid, or even version parameters if you have a robust cache-busting strategy via filenames (e.g.,script.1234.js). Most CDNs have a "Cache Key" or "Query String Whitelist/Blacklist" setting. - Why it works: By ignoring irrelevant query parameters, the CDN treats
script.js?v=1.2.3andscript.js?v=1.2.4as the same resource for caching purposes, as long as the underlyingscript.jsfile hasn’t changed and the versioning is handled elsewhere (like filename changes).
-
https://example.com/api/data?timestamp=1678886400- Diagnosis: Dynamic API responses are often requested with unique, time-sensitive query strings.
- Fix: For API endpoints that should not be cached, ensure they are not served with a
Cache-Control: public, max-age=...header. If they must be cached, use a very shortmax-age(e.g.,max-age=5ormax-age=60). - Why it works: A short
max-ageallows the CDN to serve the response for a brief period before revalidating, reducing origin load for frequently changing data.
4. Edge Caching Rules: The CDN’s Internal Logic
CDNs offer granular control over caching behavior, often overriding or supplementing origin headers.
- Diagnosis: Review your CDN’s dashboard for "Caching Rules," "Page Rules," or "Origin Rules." Look for settings that might be too restrictive or incorrectly applied.
- Fix: Implement rules that explicitly set cache TTLs for specific URL patterns. For example,
*.jpgand*.pngcould have amax-age=31536000. Ensure rules for dynamic content or APIs have short TTLs or are set tono-cache. - Why it works: These rules provide a centralized, explicit way to manage caching across your entire site, ensuring consistency and overriding potentially misconfigured origin headers.
5. Origin Shield / Centralized Cache
Some CDNs offer an "Origin Shield" or a centralized cache layer between the edge servers and your origin.
- Diagnosis: If your origin server is experiencing a high volume of requests for content that should be cached, even though edge hit rates look okay, your origin shield might not be configured or enabled.
- Fix: Enable and configure Origin Shield in your CDN settings. This forces all cache misses from the edge servers to first go to a single, central cache location before hitting your origin.
- Why it works: Instead of 100 edge servers each independently missing a cache and hitting your origin, only one central cache server hits your origin. This drastically reduces origin load and latency for cache misses.
6. Compression (Gzip/Brotli)
While not directly a cache hit rate factor, improper compression setup can indirectly impact perceived performance and lead to misconfigurations.
- Diagnosis: Check if your CDN is configured to serve compressed assets and if the
Vary: Accept-Encodingheader is present for them. - Fix: Enable Gzip and Brotli compression at the CDN level or ensure your origin is serving compressed assets with
Content-Encoding: gzip(orbr) andVary: Accept-Encoding. - Why it works: Compressed assets are smaller, faster to transfer, and when combined with correct
Varyheaders, allow the CDN to cache different compressed versions efficiently.
The next error you’ll hit is a 404 Not Found because your CDN is now correctly caching and serving content, but a resource you expected to be there has been removed from your origin.