S3 vs Spaces for public file delivery and egress costs
Compare DigitalOcean Spaces and Amazon S3 for public images, downloads, and media, with cost models that make outbound transfer visible before launch.
The short answer for public assets
For a small site serving public images, downloads, or media, Spaces is easier to budget. Its Standard subscription starts at $5 a month and includes 250 GiB of storage plus 1,024 GiB of outbound transfer across the account's Spaces buckets. Knowing the first terabyte is already covered removes one annoying variable from launch planning.
That does not make Spaces the automatic answer. Amazon S3 is a better fit when the rest of your system already lives in AWS, when you need its storage classes and access controls, or when request rate needs to scale far beyond a modest public-assets workload. S3 can cost less for a nearly empty bucket that rarely serves anything, because it has no monthly minimum.
The mistake is treating either service as a generic hard drive. Public file delivery has three moving parts: what you keep, how often software asks for it, and how much data visitors receive. A popular launch mostly changes the last one.
A bucket is a named container for files. Each stored file is an object. The origin is the service that holds the original object, while a CDN keeps cached copies closer to visitors. Ingress means data sent into storage. Egress means data sent out, such as a visitor downloading an image.
What this comparison counts
The figures compare Spaces Standard Storage with S3 Standard in US East, N. Virginia. S3 serves files directly to the public internet. CloudFront, Transfer Acceleration, replication, tax, support plans, negotiated rates, and the account-wide AWS free-transfer pool are outside this model. This is a direct-storage comparison, not a claim that an optimized AWS delivery stack has no place.
A request is one instruction to the service. A GET reads or downloads an object. A PUT writes or uploads one. DigitalOcean bills Spaces in GiB. AWS publishes these S3 Standard examples in decimal GB. One GiB is about 1.074 GB. The model uses the exact conversion, 1 GiB = 1.073741824 GB, before applying S3 list rates. A TiB is 1,024 GiB.
The S3 column uses $0.023 per GB-month, $0.004 per 10,000 GET requests, $0.005 per 1,000 PUT, COPY, POST, or LIST requests, and $0.09 per GB of direct public transfer in this volume range.
The model does not subtract AWS's first 100 GB of internet transfer. That allowance is shared across AWS services and regions, and it may already be used elsewhere in the account. This forecast assumes none remains for this bucket. It is deliberately conservative, not a claim that AWS provides no allowance.
Scroll horizontally to see all columns.
| Charge | Spaces Standard | S3 Standard direct |
|---|---|---|
| Starting monthly charge | $5 | $0 minimum |
| Storage included | 250 GiB | None |
| Public outbound included | 1,024 GiB | No workload-specific allowance modeled |
| Storage after inclusion | $0.02 per GiB-month | $0.023 per GB-month |
| Public outbound after inclusion | $0.01 per GiB | $0.09 per GB in this range |
| Request billing in model | No separate request line | GET and PUT request charges |
Ingress is usually not the bill that hurts
For this baseline, internet uploads into both services are ordinarily free. That is useful, but it is not the same sentence as public egress. A photographer can upload a 4 GB file once. Ten thousand visitors can download it 4 GB at a time. The first event is ingress. The second deserves a line in the forecast.
Spaces says inbound bandwidth never counts against its transfer allowance. There is one easy-to-miss qualification for DigitalOcean users. Traffic from a Droplet to Spaces does not consume the Spaces allowance, but it can consume the Droplet's outbound transfer allowance. A Droplet using the VPC-local resolver can reach Spaces over the internal network in supported paths. Verify that route before calling an application transfer free.
S3 also has exceptions. Internet ingress, same-Region S3-to-S3 traffic, and S3 to an AWS service in the same Region are free. Direct downloads from S3 to the public internet are a different category. The model keeps that category visible because it is the one a public asset site cannot wish away.
- Call an allowance included, not free.
- Call an internal route free only after checking the actual region and resolver path.
- Forecast public downloads separately from creator uploads and deployment traffic.
Three monthly cost models
These are not quotes. They are arithmetic with deliberately boring assumptions so you can replace the four workload inputs with your own numbers. Spaces stays at $5 for the first two models because both storage and outbound transfer remain within its subscription. The download-heavy model crosses both included amounts, so the overages become visible.
S3's request line is small here. A thumbnail service or badly cached frontend can make request volume meaningful, even when it does not dominate. The point is not that S3 requests are always expensive. The point is that they are another variable to measure.
For a quick example, the download-heavy Spaces total starts with $5. It stores 1,024 GiB, or 774 GiB above the included 250 GiB, adding $15.48. It delivers 5,120 GiB, or 4,096 GiB above the included 1,024 GiB, adding $40.96. $5 + $15.48 + $40.96 = $61.44. The table separates the inputs so you can repeat that calculation with your own numbers.
Scroll horizontally to see all columns.
| Workload | Stored | Public delivery | Requests | Spaces | S3 direct |
|---|---|---|---|---|---|
| Small asset site | 100 GiB | 100 GiB | 100k GET, 1k PUT | $5.00 | $12.18 |
| Established site | 250 GiB | 1 TiB | 2m GET, 10k PUT | $5.00 | $105.98 |
| Download-heavy site | 1 TiB | 5 TiB | 10m GET, 50k PUT | $61.44 | $524.32 |
Scroll horizontally to see all columns.
| Workload | Spaces calculation | S3 direct calculation |
|---|---|---|
| Small asset site | $5.00 subscription. The 100 GiB stored and 100 GiB delivered are within the included amounts. | Storage $2.47 + transfer $9.66 + GET $0.04 + PUT $0.01 = $12.18 |
| Established site | $5.00 subscription. The 250 GiB stored and 1 TiB delivered are within the included amounts. | Storage $6.17 + transfer $98.96 + GET $0.80 + PUT $0.05 = $105.98 |
| Download-heavy site | $5.00 + storage overage: 774 GiB x $0.02 = $15.48 + delivery overage: 4,096 GiB x $0.01 = $40.96. Total: $61.44. | Storage $25.29 + transfer $494.78 + GET $4.00 + PUT $0.25 = $524.32 |
Check the first response
- Expected result
- The estimate names the storage, request, and outbound components, and the team can explain which component changes when public traffic grows.
- Stop if
- Stop if the calculation calls included transfer free, assumes AWS's shared 100 GB allowance belongs to this workload, mixes CDN and origin results, or omits the units used by either provider.
- Next step
- Run the 100 MiB regional delivery test and replace the model inputs after the first complete month of measured traffic.
Performance depends on the path, not the logo
For a normal site serving public images or downloads, start with versioned file names and a long cache lifetime, then enable the CDN path you intend to use. A visitor can then receive a cached copy nearby instead of making every request travel back to the origin. Spaces includes its CDN with Standard Storage. The S3 baseline here is direct S3, so it does not pretend that CloudFront is already part of the same price or setup.
A public image loaded from a cache near the visitor is a different request from a private object fetched from an origin across an ocean. Compare the delivery path you will actually ship before comparing raw origin latency.
Spaces documents an 800-operations-per-second limit for new buckets, recommends its CDN above 400 reads per second, and asks teams expecting sustained workloads above about 150 requests per second to prepare with support. It also recommends multipart uploads for large files, backoff after 503 Slow Down responses, and a region chosen for the application and users.
AWS documents at least 3,500 write-type requests and 5,500 GET or HEAD requests per second per partitioned prefix for S3, with parallel prefixes used to scale further. That makes S3 a stronger candidate for very high request-rate or AWS-native systems. More headroom is useful only when the workload needs it.
Run a small test before you call anything faster
Do not publish a speed winner from one laptop and one afternoon. Network distance, cache state, object size, TLS reuse, and the visitor's connection all move the result. A fast origin in your city can still be the wrong answer for customers elsewhere.
You can start in browser developer tools. Put the same immutable 100 MiB file in each candidate store, open the Network panel, and compare a first request with repeat requests. For Spaces, test both the origin and CDN endpoint. For S3, test the direct regional endpoint in this article's baseline.
If you need a technical record, test from the regions where your users live and capture DNS lookup, connection, TLS setup, time to first byte, total transfer time, received bytes, and cache headers. Keep first and repeat requests separate.
Keep the raw results with date, region, command, endpoint type, and object cache policy. If you later add CloudFront or Transfer Acceleration, list it as a new design with its own cost. That discipline prevents a recommendation based on mismatched systems.
- Optional technical test: choose a 100 MiB immutable object and set a documented cache policy.
- Test the same object from each target region, once cold and several times warm.
- Record timings and headers, then compare like with like before changing providers.
Who should choose Spaces
Choose Spaces when public images, downloads, or media are the job and you want a monthly model that stays simple through the first 250 GiB stored and 1 TiB delivered. It fits a product site, a small SaaS serving user-visible assets, documentation downloads, and a project that already runs on DigitalOcean. S3-compatible tools and SDKs make the switch less dramatic than the provider names suggest.
Do not choose it because an article called egress free. Choose it because the included transfer and published overage rate fit your forecast, the CDN path fits your users, and its limits fit the request rate you expect. If you need private signed delivery, test that exact design. Presigned URLs do not receive normal Spaces CDN cache benefits.
Who should choose S3
Choose S3 when AWS is already the center of gravity, when its storage classes, IAM model, replication options, compliance tooling, or high request-rate behavior solve a concrete problem. A bucket that holds little data and serves little traffic can be cheaper than a $5 subscription. The absence of a minimum is a real advantage for a dormant project.
For public delivery, do not compare direct S3 with a bundled CDN as though they are the same system. If CloudFront is the design you want, price and test S3 plus CloudFront. If long-distance uploads are the problem, evaluate Transfer Acceleration as its own paid option. AWS gives you more paths. It also asks you to choose and budget for them.
How to turn this into your own forecast
Start with the last 30 days, not a hope for the next 12 months. Add the size of every object you expect to keep at month end. Then pull the bytes delivered to visitors from your current host, CDN, analytics, or application logs. If you do not have a live product yet, use a page-weight estimate multiplied by a cautious monthly download count, then write down the assumption beside the total.
Count the requests too, but do not invent precision you do not have. A static site with long cache lifetimes may make far fewer origin GETs than page views suggest. A resized-image endpoint can make several object reads for one visible image. Put a low, expected, and high delivery number in the sheet. The gap between those scenarios is often more useful than a single total because it shows whether egress is a rounding error or the first bill you need to watch.
Finally, decide who owns the alert. Set a budget alert before release, check storage and transfer separately after the first week, and record whether a CDN cache miss, bot traffic, or a real audience caused a surprise. A provider choice is easier to reverse when the team can say what changed.
The practical verdict
For a public-file project whose traffic might be a pleasant surprise, Spaces is the calmer default. The first 1 TiB of outbound transfer is included in the $5 subscription, its CDN is part of Standard Storage, and the overage rate is easy to put in a spreadsheet. Bandwidth still costs money. The first stage of growth is simply easier to explain.
Choose S3 direct for a tiny, quiet bucket or choose a fuller AWS design when AWS-specific needs justify the extra pieces. Choose Spaces when the workload is ordinary public asset delivery and cost predictability matters more than assembling every possible storage feature. In either case, set a budget alert, keep delivery metrics, and revisit the model after the first real month.