CDN
Put static things at the edge first: your frontend app and your images. Then decide, very carefully, whether any API reads should be cached too.
CDN sits in front of your origin
Put these on the CDN first
Frontend App
JS bundles, CSS, static HTML, fonts, and icons are the first thing most teams should push to a CDN.
Images
Product images, avatars, hero art, and docs screenshots benefit from caching, resizing, and compression at the edge.
Fonts
Fonts are static, reused often, and expensive to re-download. CDN delivery usually pays off immediately.
Docs + Downloads
PDFs, changelogs, installers, and other static files are natural CDN content.
Some GET APIs
Public catalog pages, config, docs metadata, or anonymous read APIs can work if TTL and headers are clear.
Not Everything
Avoid caching user-specific pages, private API responses, and write endpoints unless you really know the invalidation model.
How to use it on a cloud provider
Basic Setup
Pick an origin: static bucket, app load balancer, or image storage.
Put the CDN in front of that origin and map your domain to it.
Set cache rules: long TTL for versioned assets, careful TTL for images, strict rules for APIs.
Invalidate or version files on deploy so users get fresh content without stale cache surprises.
Cloudflare
Edge CDN, image delivery, cache rules, and easy DNS + proxy setup.
Very easy to explore if you want a strong mental model for CDN + edge proxy together.
Amazon CloudFront
AWS CDN in front of S3, ALB, EC2, or custom origins.
Common when your assets or app already live in AWS.
Google Cloud CDN
Google’s CDN in front of load balancers and backend buckets.
Good reference for CDN attached to Google Cloud load balancing.
Azure Front Door
Microsoft’s global entry layer for acceleration, routing, and caching.
Useful example when you want CDN-like edge delivery plus global front-door routing.
How teams make CDN caching real
app.get("/assets/:file", (req, res) => {
res.setHeader(
"Cache-Control",
"public, max-age=31536000, immutable"
)
return res.sendFile(req.params.file)
})