Every web page is really two things mixed together. Some of it is unique to you right now — your shopping cart, your feed, your account balance. The rest is the same for everyone: the logo, the stylesheet, the product photos, the JavaScript bundle. Yet many apps make the same hardworking server compute the personalized part and hand out the identical files, over and over, to every visitor.
Static content hosting separates those two jobs. The unchanging files get served from somewhere cheap, fast, and built for exactly that — leaving your application servers free to do the work only they can do.
The problem
When your application server delivers a 2 MB hero image, it spends connections, memory and bandwidth doing something trivial — pushing the same bytes it pushed a thousand times before. That's capacity taken from the requests that actually need application logic.
Distance makes it worse. A page isn't one download but a series of waves: the browser fetches the HTML, discovers the stylesheet and scripts it links to, fetches those, discovers the images and fonts they reference, and fetches those. Files in the same wave download in parallel, but each wave has to wait for the one before, and each one costs a full round trip to your server. For a user on the other side of the world, that's a long round trip several times over.
Below, a user in Sydney loads a page from a server in Virginia. Predict when the page finishes loading before you step forward.
You can throw more servers behind a load balancer, but that's an expensive way to solve what is, at heart, a file-serving problem — and it does nothing for the user in Sydney, whose waiting is caused by the ocean, not by your servers.
How it works
You upload static assets to a cloud object store — a service designed to hold and serve files cheaply and reliably. Then you put a CDN (content delivery network) in front of it: a global mesh of edge servers that keep cached copies of your files close to where users are, applying caching at the network edge.
An edge starts out empty. The first request for a file at that edge is a miss: the edge fetches the file from storage, passes it on, and keeps a copy for as long as its time-to-live (TTL) allows. Every request after that is a hit, answered from nearby without touching storage at all. Meanwhile your app server only builds the dynamic parts, such as the HTML.
Step through two visitors in Sydney and predict how long the second one waits. Then you'll deploy a fix to app.js and choose how to publish it — try both choices with the toggle.
You put your images and scripts behind a CDN, but users in Australia report the page is still slow on their first visit of the day. Which explanation fits best?
Cache invalidation is the trap. A CDN's whole value is holding onto copies, so if you overwrite app.js in place, edges keep serving the old version until its TTL runs out — and browsers may have cached it too. Users then get new HTML with old JavaScript, a mix nobody tested. The standard fix is fingerprinting: bake a content hash into the filename (app.3f9c.js), so a changed file gets a brand-new URL that no cache has ever seen. Fingerprinted files can be cached for a year; only the small HTML that points to them needs a short TTL. Most build tools can do this for you.
When to use it
This is close to a default for any public web app or single-page application. The moment you're serving images, fonts, stylesheets, client-side bundles, or downloadable files, moving them to storage plus a CDN cuts load on your servers and slashes latency for distant users — usually for less money than running extra app capacity.
Where it fits less neatly is content that's genuinely per-user or needs strict access control on every fetch. You can serve private assets through a CDN with signed URLs, but if nearly everything is dynamic and personalized, the static-hosting win is small. And remember what the scene showed: the CDN speeds up the files, not the HTML your app server still builds per visitor. The sweet spot is the large, shared, rarely-changing files that every visitor needs.
After a deploy, some users see a broken page until they clear their cache. Your build overwrites main.js in storage on every release. What change prevents this?