CalculatorCase StudyGuidesWikiChecklistSimulatorAbout
All Guides
Infrastructure8 min

Cache is your cheapest employee

The right Cache-Control headers can reduce your hosting costs by 90%. Here's the cheat sheet that hosting providers don't include in their docs.

01

CDN before origin — always

The single most impactful thing you can do for hosting costs: put a CDN in front of your origin server. Cloudflare's free tier is enough for most projects. Every request that hits the CDN cache is a request that doesn't hit your server.

At $0.15/GB bandwidth on Vercel vs effectively $0 on Cloudflare's free CDN, the math is obvious. jmail.world's estimated ~$10k bandwidth bill would have been near zero if they'd put Cloudflare in front from day one. This isn't optimization — it's table stakes.

02

The Cache-Control cheat sheet

Static assets with fingerprints (JS/CSS bundles with hash in filename): public, max-age=31536000, immutable. These never change — the filename changes when content changes. Cache them forever.

Static HTML and JSON: public, max-age=2592000, stale-while-revalidate=86400. 30 days with a 1-day SWR window. Content changes infrequently; users get instant loads while the CDN refreshes in the background. Archival content that never changes: public, max-age=2592000. 30 days, no SWR needed.

Dynamic API responses: public, max-age=60, stale-while-revalidate=300. 1 minute fresh, 5 minutes stale-but-served. Authenticated user data: private, no-cache. Never CDN-cache user-specific data.

03

stale-while-revalidate explained

SWR is the single most underused Cache-Control directive. Here's what it does: when the cache expires, instead of making the user wait for a fresh response, the CDN serves the stale content immediately and fetches a fresh copy in the background. The user gets instant response.

The CDN gets updated. Nobody waits. For most content, 'stale by 5 minutes' is perfectly acceptable.

Your blog post, your product page, your documentation — none of it needs to be fresher than 5 minutes. But without SWR, an expired cache means a cold request to origin, which means latency for the user and cost for you.

04

When NOT to cache

Not everything should be cached. User-specific data (profile, cart, auth tokens) must be private, no-cache. Real-time data (stock prices, live scores) needs short TTLs or no caching.

POST/PUT/DELETE responses shouldn't be cached. Anything behind authentication should use private caching at most. The mistake people make: caching too little, not too much.

Default to 'cache everything' and carve out exceptions for the few truly dynamic endpoints. Most of your application serves the same content to everyone — cache it.

05

Images: the bandwidth killer

Images are often 60-80% of a page's weight. jmail had a 650KB PNG Facebook icon served to every visitor. The fix: use a separate image CDN (Cloudflare Images, imgix, Cloudinary). These services handle format conversion (WebP/AVIF), responsive sizing, and aggressive caching automatically.

Even the free tiers are generous enough for most projects. The alternative — serving unoptimized images from your origin — is the fastest way to a surprise bandwidth bill.

06

Static export: the ultimate cache strategy

If your site can be statically generated, you've already won. Static files are infinitely cacheable, cost nothing to serve from a CDN, and require zero origin compute. That's why HostCost uses output: 'export' — every page is a plain HTML file deployed to a CDN.

There's no server to hit, no function to invoke, no compute to bill. The hosting cost is effectively $0 (for our current static-export setup, within a free tier). For content sites, marketing pages, documentation, and tools with client-side interactivity — static export is the most cost-effective architecture possible.

next steps

Want to see these principles in action?