1. Split the bill into five line items#

Comparing object storage on the GB-month rate alone is like comparing phone plans on the per-minute price. Every pricing page lists that rate, but your final bill depends on how many operations you run, how much data leaves for the internet, and whether the provider applies a minimum charge or a minimum storage duration.

Before looking at providers, describe your workload with five monthly numbers: average storage, writes, reads, data leaving to the internet, and the average lifetime of each object. With those you can price any public rate card; without them, any comparison is a hunch.

  • Storage: the month's average volume, not the peak. Billed as GB-month or GiB-month.
  • Operations: PUT, GET, LIST, HEAD and similar calls, grouped into classes with different prices.
  • Egress: data leaving the provider for the internet or another cloud.
  • Minimums: base subscriptions, included allowances, and minimum billable object sizes.
  • Minimum retention: days you pay for even if you delete the object earlier, typical of infrequent-access or cold tiers.

This guide uses the same reviewed figures as the Codifly storage comparator for AWS S3 Standard in N. Virginia, Cloudflare R2 Standard, Backblaze B2 Pay as you go, and DigitalOcean Spaces Standard. If what you need is to upload files from the browser without exposing the bucket, the guide on direct uploads with presigned URLs covers that flow; here we focus on cost.

Go deeper: Direct Uploads to S3: Presigned URLs Without Exposing Your Files

2. GiB vs GB: the 7.4% gap nobody checks#

A decimal GB is 10⁹ bytes; a GiB is 2³⁰ bytes, or 1,073,741,824 bytes. AWS documents that S3 measures storage in binary gigabytes, where 1 GB equals 2³⁰ bytes. DigitalOcean publishes Spaces prices directly in GiB. Cloudflare's R2 pricing page lists rates in GB without stating the base, and Backblaze prices per TB.

If your inventory says 1,000 decimal GB and the provider bills in GiB, you will be billed for about 931.32 GiB. To compare rates in the same unit, divide the per-GiB rate by 1.073741824. The comparator does exactly that: S3's $0.023 per GiB-month becomes roughly $0.02142 per decimal GB, and Spaces' $0.02 per additional GiB-month roughly $0.01863.

python
GIB = 2**30 / 10**9  # 1.073741824 decimal GB per GiB

def rate_per_decimal_gb(rate_per_gib: float) -> float:
    return rate_per_gib / GIB

def gib_from_gb(decimal_gb: float) -> float:
    return decimal_gb / GIB

print(round(rate_per_decimal_gb(0.023), 5))  # S3 Standard: 0.02142
print(round(gib_from_gb(1000), 2))           # 1,000 GB = 931.32 GiB
Minimal conversion to normalize rates. Only apply it when the provider documents binary units.

The gap looks small, but it compounds at volume and muddles reconciliation: your monitoring reports decimal GB, the invoice shows a different number, and someone loses an afternoon chasing an error that does not exist. Pick one unit for your spreadsheet and document the conversion.

Documentation: AWS: S3 pricing and binary GB ↗ · DigitalOcean: Spaces pricing in GiB ↗

3. Operations come in classes with different prices#

Every API call against a bucket is a billable operation unless the provider declares it free. Providers group operations into classes: calls that write or list usually cost far more than simple reads. An application that lists the bucket on every request can pay more for LIST than for storing its files.

ProviderWrites and listingsReadsFree or included
S3 Standard (us-east-1)PUT, COPY, POST, LIST: $0.005 per 1,000GET, SELECT: $0.0004 per 1,000DELETE and CANCEL are free
R2 StandardClass A (PutObject, ListObjects): $4.50 per millionClass B (GetObject, HeadObject): $0.36 per million1M Class A and 10M Class B per month; DeleteObject free
Backblaze B2PutObject (Class A) and ListObjects (Class C): freeGetObject, HeadObject (Class B): freeClasses A, B and C free; Class D (event notifications): $0.004 per 10,000 after 2,500 free per day
Spaces StandardNo published per-request rateNo published per-request rateThe pricing page lists no per-operation charges

Per million, S3 charges $5 for PUT and $0.40 for GET; R2 charges $4.50 and $0.36. The real difference shows up once you subtract R2's included allowances and check which operation lands in which class: on R2, ListObjects is Class A, just like a write.

Measure operations from your current bucket's logs or metrics, not from an estimate based on endpoints. SDK retries, multipart uploads, and on-the-fly thumbnails multiply calls compared with what the user sees.

Documentation: AWS: S3 request pricing ↗ · Cloudflare: R2 operation classes ↗ · Backblaze: B2 transaction classes ↗ · DigitalOcean: Spaces pricing ↗

4. Egress is often the biggest line item#

Egress is traffic leaving the provider. For a bucket that serves images, downloads, or video straight to the public, it often exceeds storage. That is why differences in egress policy matter more than differences in the GB-month rate.

  • S3: internet egress from us-east-1 costs $0.09 per GB in the first tier; the first 100 GB per month are free, but that allowance is shared across all AWS services and Regions.
  • R2: egress to the internet is free, for both Standard and Infrequent Access.
  • B2: includes free egress up to three times your average monthly storage; overage is billed at $0.01 per GB.
  • Spaces: the subscription includes 1,024 GiB of outbound transfer; extra traffic costs $0.01 per GiB, and inbound traffic never counts against that allowance.

A CDN in front of the bucket changes this line item but does not remove it: cache misses still leave the origin, and the CDN has its own pricing. Model the cache hit ratio you actually observe, not the one you hope for.

Documentation: AWS: S3 data transfer ↗ · Cloudflare: R2 egress ↗ · Backblaze: B2 egress policy ↗ · DigitalOcean: Spaces transfer ↗

5. Monthly minimums and minimum retention#

Spaces Standard has a $5 monthly base subscription that includes 250 GiB of storage shared across all your buckets; additional storage costs $0.02 per GiB-month. Billing starts with your first bucket and ends when you destroy all of them. For a small project, that minimum is what you will pay even if you store only a few GB.

At the other end, R2 includes 10 GB-month, 1 million Class A and 10 million Class B operations per month on Standard, and B2 includes the first 10 GB of storage. S3 Standard has no minimum storage duration and no minimum object size.

Minimum retention shows up in tiers meant for rarely accessed data. S3 Standard-IA charges a 30-day minimum and a 128 KB minimum billable object size. R2 Infrequent Access has a 30-day minimum and a $0.01 per GB retrieval fee. Spaces Cold Storage also requires 30 days of minimum retention. B2 states it applies no minimum storage duration or minimum file size.

If your objects are short-lived, such as exports deleted after a few days or quarantined uploads, an infrequent-access tier can end up costing more than Standard even with a lower per-GB rate: you pay for the full 30 days.

Documentation: DigitalOcean: Spaces subscription and Cold Storage ↗ · Cloudflare: R2 allowances and Infrequent Access ↗ · Backblaze: B2 storage terms ↗ · AWS: S3 Standard-IA minimums ↗

6. Worked example: 1 TB with public traffic#

Assumptions: 1,000 decimal GB of average storage (931.32 GiB), 5 million PUTs, 50 million GETs, and 1,000 GB of internet egress per month. Published first-tier rates, no taxes, no new-account credits, and no other AWS services consuming the free transfer allowance. Egress is taken in each provider's published unit, without conversion.

text
S3 Standard (us-east-1)
  storage   931.32 GiB × $0.023             = $21.42
  PUT       5,000 × $0.005 per thousand     = $25.00
  GET       50,000 × $0.0004 per thousand   = $20.00
  egress    (1,000 − 100) GB × $0.09        = $81.00
  total                                     = $147.42

R2 Standard
  storage   (1,000 − 10) GB × $0.015        = $14.85
  Class A   (5M − 1M) × $4.50 per M         = $18.00
  Class B   (50M − 10M) × $0.36 per M       = $14.40
  egress    free                            = $0.00
  total                                     = $47.25

Backblaze B2
  storage   (1,000 − 10) GB × $0.00695      = $6.88
  PUT, GET  Classes A and B free            = $0.00
  egress    1,000 GB < 3 × 1,000 GB         = $0.00
  total                                     = $6.88

Spaces Standard
  base      includes 250 GiB and 1,024 GiB  = $5.00
  storage   (931.32 − 250) GiB × $0.02      = $13.63
  egress    931.32 GiB < 1,024 GiB          = $0.00
  total                                     = $18.63
B2 is priced as in the comparator: $6.95 per TB converted to $0.00695 per GB. Amounts rounded to cents.
Provider1 TB scenario20 GB bucketWhat drives the cost
S3 Standard$147.42$1.33Egress and operations
R2 Standard$47.25$0.15Class A and B operations
Backblaze B2$6.88$0.07Storage
Spaces Standard$18.63$5.00Minimum subscription

The 20 GB column assumes 100,000 PUTs, 1 million GETs, and 20 GB of egress. On S3: 20 GB is 18.63 GiB × $0.023 = $0.43, plus $0.50 of PUTs and $0.40 of GETs; egress stays within the free 100 GB. On R2 and B2 everything fits within the included allowances except 10 GB of storage. On Spaces you pay the $5 minimum.

The ranking shifts with your pattern. If the bucket is a backup that rarely leaves for the internet, S3's egress disappears and the gap narrows. If you list heavily, R2 climbs. And if you store little, the Spaces minimum outweighs any rate. We also leave out performance, regions, compliance, and integration with the rest of your cloud, which can justify paying more.

Documentation: AWS: S3 pricing ↗ · Cloudflare: R2 pricing ↗ · Backblaze: B2 pricing ↗ · DigitalOcean: Spaces pricing ↗

7. Checklist before choosing a provider#

  • Measure average storage, PUT, GET, LIST, and egress over the last three months using real data.
  • Note the unit of each rate (GB, GiB, or TB) and normalize before comparing.
  • Identify which class each operation falls into, especially listings.
  • Check whether each included allowance applies per account or per bucket before subtracting it.
  • Calculate egress with your real CDN cache hit ratio.
  • Check monthly minimums and minimum retention if you use infrequent or cold tiers.
  • Include what the bucket price does not cover: CDN, compute, managed encryption, replication, and migrating existing data.
  • Rerun the numbers at twice the traffic to see which provider scales worst.
  • Recheck rates on the official page before committing: they change without notice.

The Codifly storage comparator shows marginal rates normalized to decimal GB, with caveats per provider. Use it as a starting point and replace the assumptions with your own metrics.

Sources and scope

Documentation checked on September 26, 2026. Examples and decision criteria are editorial proposals; adapt them to your application's contract and validate them in an authorized test environment.

From design to decision

Compare object storage

Review pricing, limits, conditions and sources for each option.

Open comparison