✦ Preferences saved
Web Performance Jul 11, 2026 5 min read Fixed

Two Subdomains, Same Host, Different Cache Headers

identical .htaccess · identical origin · 7-day cache on one, 1-year on the other

7d → 1y
Cache lifetime fixed
0
Downtime
1 line
Actual fix
s-maxage
The directive

The symptom

Two subdomains on the same hosting account, same CDN product, same server. Running a font request through DevTools on both:

devtools · response headers
domain-a.tld  →  Cache-Control: public, max-age=31536000, immutable   # 1 year
domain-b.tld  →  Cache-Control: public, max-age=604800                  # 7 days

Same file type (.woff2), same account. GTmetrix and PageSpeed Insights flag anything under Lighthouse's ~3-month cache threshold as an "inefficient cache policy" — so this wasn't cosmetic, it was actively hurting the performance score on one subdomain and not the other.

What I ruled out first

Before touching any configuration, I compared the two .htaccess files line by line:

.htaccess
<IfModule mod_headers.c>
    <FilesMatch "\.(css|js|woff2?|svg|png|jpe?g|webp|avif|ico)$">
        Header set Cache-Control "public, max-age=31536000, immutable"
    </FilesMatch>
</IfModule>

Identical directive, identical value, on both domains. So this wasn't a misconfigured origin — the server was telling both zones to cache for a year. Something between the origin and the browser was overriding that on one of the two.

Isolating the layer

The host's CDN dashboard has no per-domain TTL override and no "respect origin headers" toggle exposed in the UI — confirmed directly from their own documentation, not assumed. So the CDN itself was silently applying a different default per zone, with no dashboard setting to fix it.

To confirm the origin was actually correct (and rule out anything server-side), I used the CDN's "development mode" to bypass the edge cache entirely and hit the origin directly. Result: origin returned the correct 1-year header, every time, on both domains. The discrepancy was 100% happening at the CDN layer, not the server.

The fix

Added s-maxage alongside max-age in the same directive:

.htaccess · the fix
Header set Cache-Control "public, max-age=31536000, s-maxage=31536000, immutable"

s-maxage is the directive shared/proxy caches (CDNs) are supposed to prioritize over max-age. The CDN zone that was defaulting to 7 days had apparently never been reading max-age correctly for its internal TTL — but it did honor s-maxage.

After purging cache and testing a fresh (never-before-cached) URL through the live CDN edge — not bypass mode, not stale cache, an actual MISS-then-HIT — the header came back exactly as expected:

devtools · after fix, live edge
Cache-Control: public, max-age=31536000, s-maxage=31536000, immutable
X-Cache-Status: MISSHIT

Fixed. Fixed. No CDN downtime, no DNS changes, no migration, no design changes. One directive.

Why this is worth sharing

Nothing about this is officially documented anywhere I could find. Support could confirm the two zones behaved differently but couldn't explain why or how to align them from the panel. The fix came from testing directive-by-directive against the actual delivered headers — not from a knowledge base article.

i

Takeaway: If you're on a CDN with no visible per-domain cache controls and you're seeing inconsistent Cache-Control headers across subdomains on the same account: check s-maxage before you consider disabling the CDN or migrating providers. It cost nothing to test and it was the actual fix.

#webperf #caching #cdn #htaccess #debugging #hosting
FIELD NOTES