If you’re comparing cloudflare r2 vs s3, you’re probably trying to cut egress bills, simplify object storage, or both—especially when your app runs on a VPS and every extra moving part shows up as latency, complexity, or surprise costs.
What matters for VPS-hosted workloads
When your compute lives on a VPS (say on digitalocean or hetzner), object storage isn’t just “a bucket somewhere.” It’s part of the request path.
For most VPS-hosted apps, the decision comes down to four practical questions:
- Egress costs: Are you paying to deliver user-facing assets (images, downloads, video) from storage?
- Compatibility: Can your app/tooling speak S3 APIs without rewrites?
- Latency & edge delivery: Can you put content close to users without bolting on more services?
- Operational simplicity: How many knobs do you need to turn to keep it secure and fast?
If your storage is purely internal (backups, logs, ML artifacts), you’ll care more about durability and lifecycle tooling. If it’s user-facing (static assets, media), you’ll care a lot about egress and CDN integration.
Cloudflare R2: the “egress-first” object store
R2’s headline feature is simple: no egress fees (for typical outbound scenarios), which is a big deal when you’re serving files to the public internet.
Why that matters on a VPS:
- You can keep your app on a VPS and push all heavy bytes (images, uploads, downloads) to R2 without being punished when traffic grows.
- R2 fits naturally with Cloudflare’s edge ecosystem. If you’re already using cloudflare for DNS, caching, WAF, or Workers, R2 tends to reduce the “glue code” you’d otherwise maintain.
Trade-offs to be aware of:
- It’s not AWS. The S3 API compatibility is good for common operations, but some AWS-specific features or edge cases may not translate 1:1.
- Ecosystem depth: AWS has decades of add-ons, IAM patterns, and third-party tooling assumptions. R2 is newer, so you’ll hit “this guide assumes AWS” more often.
My take: for VPS hosting where you’re distributing user-facing files, R2 is often the default choice now—because egress is the silent killer of “cheap” storage.
Amazon S3: the standard for a reason (and the bill for a reason)
S3 is still the reference implementation for object storage. It’s stable, extremely feature-complete, and the surrounding ecosystem is unmatched.
Strengths that matter in practice:
- Best-in-class durability and maturity: It’s boring in the best way.
- Lifecycle policies & storage classes: If you’re cost-optimizing at scale (archival, infrequent access), S3 has many levers.
- Integrations everywhere: Backup tools, CI pipelines, data tooling, security scanners—most support S3 first.
The downside for VPS-hosted web apps is predictable:
- Egress and request costs can dominate when you serve a lot of public traffic.
- CDN integration usually becomes mandatory to control performance and cost (which adds another service to configure and reason about).
My take: if your object storage is internal-facing, compliance-heavy, or deeply integrated with AWS services, S3 remains hard to beat. If you’re just serving files to users, S3 can feel like paying a “tax” for features you don’t use.
Hands-on: switching an app to R2 (S3-compatible) from a VPS
Most VPS apps can talk to R2 using the S3 API. That means you can often swap endpoints and credentials without rewriting storage logic.
Here’s a minimal AWS CLI example you can run from any VPS (including hetzner or digitalocean) to test uploads to R2:
# 1) Configure a named profile for R2 (use your R2 access keys)
aws configure set aws_access_key_id "$R2_ACCESS_KEY_ID" --profile r2
aws configure set aws_secret_access_key "$R2_SECRET_ACCESS_KEY" --profile r2
aws configure set region "auto" --profile r2
# 2) Upload a file to a bucket using the R2 endpoint
aws s3 cp ./logo.png s3://my-bucket/logo.png \
--profile r2 \
--endpoint-url "https://<accountid>.r2.cloudflarestorage.com"
# 3) List objects (sanity check)
aws s3 ls s3://my-bucket/ \
--profile r2 \
--endpoint-url "https://<accountid>.r2.cloudflarestorage.com"
Operational notes:
- Treat R2 like S3 for basics (buckets, objects, presigned URLs), but verify any advanced features you depend on.
- If you currently generate presigned URLs for uploads/downloads, test them early—edge cases tend to show up there.
So which should you choose for VPS hosting?
Here’s the opinionated decision rule that holds up in real deployments:
- Choose Cloudflare R2 if you’re serving public assets, downloads, or user uploads and you want predictable bills. “No egress fees” is not a minor pricing detail—it changes architecture decisions.
- Choose Amazon S3 if your workload is AWS-native, you need the broadest feature set, or you’re building data workflows where the AWS ecosystem saves more engineering time than the egress costs.
A practical hybrid is common: keep internal backups or data pipeline artifacts in S3, and put user-facing blobs in R2 (especially if you already rely on cloudflare at the edge).
If you’re hosting on a VPS provider like digitalocean or hetzner, R2 can be a clean way to get “CDN-adjacent” object storage behavior without adding extra layers. That said, if your team already has strong AWS operational muscle memory, S3’s maturity can be worth the cost—even when it stings.
Some links in this article are affiliate links. We may earn a commission at no extra cost to you if you make a purchase through them.
Top comments (0)