Cloudflare R2 vs S3: Object Storage for VPS Apps

Published: (April 28, 2026 at 10:14 PM EDT)
4 min read
Source: Dev.to

Source: Dev.to

Typical VPS workloads

Object storage is your durable “bucket of blobs” for:

  • User uploads (images, videos, PDFs)
  • Backups and archives
  • Static assets for web apps
  • Data pipelines (logs, exports)

Deciding factors

  • Egress costs – moving data out to the public internet or to your VPS
  • Latency – distance from your compute to the storage endpoint
  • S3 API compatibility – tooling and SDK friction
  • Operational ergonomics – IAM, policies, lifecycle rules

Why R2 stands out

  • Zero egress fees in many common scenarios, which can flip the cost math for serving files or syncing content across regions.
  • Tight integration with Cloudflare’s edge network and caching layer.

Note: “No egress” does not mean “no cost.” You still pay for storage and operations, and request pricing should be validated against your access pattern.

Cost considerations

  • S3: Storage pricing is usually modest; networking (egress + request fees) often dominates, especially for public downloads or chatty workloads.
  • R2: Eliminates most egress fees, but you still incur storage and request charges.

If your app is asset‑heavy (images, downloads, media), model egress first. A sudden traffic spike on a small VPS can make S3 egress a surprise that forces a redesign.

Latency & geography

  • If your VPS sits near an AWS region, S3 latency is predictable.
  • For globally distributed users, a CDN in front of either service often matters more than raw bucket latency.
  • R2 lives closer to Cloudflare’s edge, making it a natural fit when you already use Cloudflare’s CDN/DNS.

Feature comparison

FeatureAmazon S3Cloudflare R2
Durability & ecosystem maturity✔️ Great durability, massive ecosystem✔️ Good durability, growing ecosystem
Egress pricingPaid per GB (can be costly)Free in many scenarios
Request pricingPaid per requestPaid per request (generally comparable)
IAM & policy toolingMature, fine‑grainedSimpler, still evolving
Lifecycle managementDeep options (transition, expiration)Basic lifecycle rules
Broad integrationBackups, CI/CD, data platforms, many third‑party toolsCompatible with many S3‑aware tools, but fewer native integrations
S3 compatibilityNativeS3‑compatible for most operations (most SDK calls work)
Edge‑case behaviorFull AWS feature setMay differ on advanced IAM or specific AWS integrations

Tip: If you rely on edge‑case S3 behaviors, test your toolchain against R2 before committing.

Minimal Node.js example (AWS SDK v3)

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

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

async function upload() {
  const Body = fs.createReadStream("./avatar.png");
  const cmd = new PutObjectCommand({
    Bucket: process.env.R2_BUCKET,
    Key: "uploads/avatar.png",
    Body,
    ContentType: "image/png",
  });

  await client.send(cmd);
  console.log("Uploaded");
}

upload().catch(console.error);

If you can upload, list, and read objects with your existing tooling, most migrations become a pricing decision rather than a rewrite.

Decision guide

  • Choose S3 if you’re deeply tied to AWS services, need the most mature IAM/policy surface, or want maximum “it just works” integration with third‑party tools.
  • Choose Cloudflare R2 if egress is a major risk, you serve lots of public content, or you want an S3‑like workflow without typical bandwidth penalties.

For lean VPS stacks (e.g., DigitalOcean droplets or Hetzner servers), R2 can keep bills predictable while still using familiar S3 tooling. If you already use Cloudflare for DNS/CDN, the operational simplicity is a nice bonus—but it shouldn’t be the sole reason for the switch.

0 views
Back to Blog

Related posts

Read more »