DEV Community

Juan Diego Isaza A.
Juan Diego Isaza A.

Posted on

Cloudflare R2 vs S3: Best Object Storage for VPS?

If you’re running a VPS-hosted app and your bandwidth bill is creeping up, cloudflare r2 vs s3 is the comparison that actually moves the needle—because it’s less about raw storage price and more about egress, latency, and operational friction.

The real difference: egress economics (VPS reality)

On paper, object storage is cheap. In practice, VPS workloads pay for traffic. Backups, media delivery, AI artifacts, logs, user uploads, and CI build caches can turn into constant read-heavy flows.

Amazon S3 is the default for a reason: it’s reliable, feature-rich, and universally supported. But for many VPS deployments, the surprise is egress and request costs—especially when you put a CDN in front, serve lots of small objects, or pull data frequently across regions.

Cloudflare R2 is built to attack that exact pain: it’s S3-compatible and positioned around “no egress fees” (you still pay for operations and storage). In a VPS_HOSTING context, that often means:

  • If your app is bandwidth-heavy, R2 can be materially cheaper.
  • If your app is compliance-heavy or needs niche AWS features, S3 stays compelling.

Opinionated take: if your monthly object traffic is unpredictable, S3 can feel like a variable tax. R2 tends to make costs more linear.

Performance & architecture: where your VPS sits matters

For VPS hosting (think digitalocean, hetzner, Linode, Vultr), the “best” storage depends on network path:

  • S3 shines when your compute is already in AWS or very close to a specific region. Cross-cloud or cross-continent traffic adds latency and cost.
  • cloudflare R2 integrates naturally with Cloudflare’s edge and Workers ecosystem, which can reduce round trips for globally distributed reads.

A practical pattern for VPS deployments:

  • Use your VPS for compute (API, background jobs).
  • Put static/user-uploaded assets in object storage.
  • Put a CDN in front.

If you already run Cloudflare in front of your site, R2 often becomes the path of least resistance. If you’re deep in AWS (IAM, VPC endpoints, private networking), S3 is still the “boring and correct” choice.

Features & compatibility: S3 is the superset, R2 is the 80/20

S3 has decades of accumulation: replication options, lifecycle policies, inventory, eventing, deep IAM controls, and a huge ecosystem of tooling. R2 focuses on the core: store objects, fetch objects, keep it compatible.

What matters for typical VPS workloads:

  • S3 API compatibility: R2 supports an S3-compatible API, which means your existing tools may work with minimal changes.
  • IAM and policy model: AWS IAM is powerful but can be complex; R2’s access model is simpler.
  • Advanced features: If you require very specific AWS integrations (some eventing patterns, analytics tooling, or niche compliance setups), S3 is hard to beat.

Opinionated take: most VPS teams don’t need the entire S3 feature universe—they need “reliable blob storage that doesn’t punish downloads.” That’s where R2 feels refreshing.

Actionable example: use the same S3 client against R2

If your app already talks to S3, you can often point it to R2 with an endpoint change. Here’s a minimal Node.js example using AWS SDK v3 to upload an object to R2.

import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";

const client = new S3Client({
  region: "auto",
  endpoint: process.env.R2_ENDPOINT, // e.g. https://<accountid>.r2.cloudflarestorage.com
  credentials: {
    accessKeyId: process.env.R2_ACCESS_KEY_ID,
    secretAccessKey: process.env.R2_SECRET_ACCESS_KEY,
  },
});

async function upload() {
  const cmd = new PutObjectCommand({
    Bucket: process.env.R2_BUCKET,
    Key: "uploads/hello.txt",
    Body: "hello from my VPS",
    ContentType: "text/plain",
  });
  await client.send(cmd);
  console.log("uploaded");
}

upload().catch(console.error);
Enter fullscreen mode Exit fullscreen mode

Notes from the trenches:

  • Many libraries assume AWS-specific defaults; always set the endpoint explicitly.
  • Keep your bucket naming and paths consistent so you can migrate back and forth.
  • Test with your real object sizes and access patterns (lots of tiny files behaves differently than fewer large files).

Choosing for VPS hosting: my rule-of-thumb matrix

Here’s how I’d decide for a typical VPS stack hosted on hetzner or digitalocean:

  • Choose Cloudflare R2 when:

    • You serve lots of downloads or public assets and want to minimize bandwidth-related surprises.
    • You already use Cloudflare for DNS/CDN/WAF.
    • You want S3-like tooling without AWS’s cost model.
  • Choose Amazon S3 when:

    • Your compute runs in AWS (or you rely on tight AWS-native integrations).
    • You need advanced governance/compliance features and mature auditing.
    • You depend on specific S3 behaviors/features that your tooling assumes.

Soft recommendation (not a hard sell): if your VPS provider is outside AWS—common with hetzner, digitalocean, Linode, or Vultr—trying R2 for static assets and backups is a low-risk experiment. You can keep your interface S3-compatible and measure real costs before committing.


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)