S3 vs CDN: Which One Actually Serves Your Assets?
S3 stores your files; a CDN serves them fast and cheap at the edge. Here's when you need each, with real numbers and how Vylara provisions storage.

S3 and a CDN are not competitors — they are two layers of the same stack. S3 is where your files physically live; a CDN caches copies of those files at edge locations close to your users. For a low-traffic app, S3 alone works fine and costs almost nothing. The moment you have global users, heavy image or video traffic, or egress bills that make you flinch, you put a CDN in front of S3 so most requests never touch the bucket at all. So the real question is not "S3 or CDN," it’s "when does adding the CDN layer start paying for itself?" For most small apps the answer is "not yet" — but knowing where the line sits saves you from both over-engineering early and surprise bills later.
What each layer is actually good at #
S3 is durable object storage: 11 nines of durability, pay-per-GB storage (roughly $0.023/GB-month in us-east-1), and per-request charges that are fractions of a cent. It will happily serve files directly over HTTPS. What it won’t do is serve them fast to someone in Singapore when your bucket lives in Virginia — that request crosses an ocean every single time, adding 150–250ms of latency and billing you full data-transfer-out rates (around $0.09/GB for the first tier) on every byte. For a handful of requests that cost is invisible. At scale, both the latency and the transfer line add up.
A CDN like CloudFront fixes both problems by caching objects at edge locations worldwide. The user in Singapore hits a nearby edge, latency drops to tens of milliseconds, and — this is the part people miss — the request never reaches S3, so you stop paying S3’s per-request and egress costs on cache hits. CloudFront’s own egress is also cheaper at scale, and its first 1 TB per month is covered by the AWS free tier. The trade-off is real: you now manage cache invalidation, and you have two things to configure instead of one. For small sites that overhead can outweigh the savings, which is exactly why you shouldn’t reach for a CDN by reflex.
A simple decision rule #
If your assets are small, your users are regional, and your monthly egress is measured in gigabytes rather than terabytes, S3 with a signed URL (preferred over blanket public-read) is enough. Add a CDN when any of three things becomes true: your users are globally distributed and complaining about load times, your monthly S3 data-transfer-out climbs past a few dollars, or you’re serving the same large files to many people repeatedly. For a marketing site with a few hundred megabytes of images and modest traffic, you might never cross that line. For a product serving user-uploaded media at scale, the CDN usually pays for itself within the first terabyte, because cache hits replace expensive direct bucket reads.
There’s also a cost-drift angle worth naming: a bucket that’s cheap in staging can quietly balloon in production because egress scales with real traffic. If you’ve read why staging costs can mislead you, the same logic applies here — the storage line is predictable, the transfer line is the one that surprises you. Measure transfer-out before you optimize anything else, because that number, not the storage bill, tells you whether an edge layer is worth it.
How Vylara sees storage in your repo #
Vylara’s agent engine reads your repository and infers what infrastructure the app needs before you ever write a config file. When it finds @aws-sdk/s3, multer, or formidable in your dependencies, it flags that your app needs file storage and presents a plain "Your app needs" card — a storage bucket at roughly $1/mo for light usage — with the choice to either create it in your own AWS account or point at a bucket you already own. You review that decision in a diff before anything is provisioned; nothing is created silently.
Two honest limits here. First, Vylara provisions the storage bucket and wires its connection details into your service as environment variables; the detection is about where your files live, so the agent leads with the S3 layer because that’s what your code references. Second, the cloud environment is created on your first deploy, not when a config PR merges — merging the PR from vylara-ai[bot] updates your repo, and the deploy step is what actually stands up the bucket in your account. After launch, you can open the infrastructure chat and ask about your storage costs or request changes, with any write action gated behind your approval.
Owning the whole thing #
Because every resource lands in your AWS account, you’re never locked into a middleman for hosting — the bucket, its data, and its bill are yours, and you can revoke Vylara’s access and keep everything. That’s the core of what it means to deploy without a DevOps team on your own cloud: the agent does the analysis, config generation, and provisioning, but ownership and the AWS bill flow straight to you. If you’re weighing the broader build-vs-managed question, managed AWS hosting versus doing it yourself breaks down where the real cost lives.
The practical takeaway: start with S3, measure your egress, and layer a CDN in front once the traffic justifies it. Both live in your account either way, so adding the CDN later is an incremental change, not a migration. You don’t have to make the perfect call on day one — you have to make the cheap, reversible call on day one and let the numbers tell you when to add the edge.
Review your cloud plan in Vylara, merge delivery changes as Git PRs, and deploy into your own AWS or Azure account when you’re ready.
Start freeFrequently asked questions
- Do I need a CDN if I'm already using S3?
- Not always. S3 can serve files directly over HTTPS, which is fine for regional users and low egress. Add a CDN when users are globally distributed, load times suffer, or your S3 data-transfer-out climbs past a few dollars a month — the CDN then serves most requests from the edge and cuts both latency and S3 costs.
- How much does serving assets from S3 actually cost?
- Storage is roughly $0.023 per GB-month, and data transfer out starts around $0.09 per GB in the first tier. Storage is predictable; the transfer line scales with traffic and is where bills surprise people. A light-usage bucket often runs around $1/month, which is what Vylara estimates on its "Your app needs" card.
- Does Vylara set up storage automatically when it finds S3 in my code?
- It detects storage dependencies like aws-sdk/s3 or multer and offers to provision a bucket in your own AWS account, but nothing is created without your approval. You review the decision in a diff, and the bucket is actually stood up on your first deploy, not when the config PR merges.



