SaaS stacks
Mara Lindqvist6 min read9 views

UploadThing vs Amazon S3 vs Cloudflare R2: File Uploads for a Next.js SaaS (2026)

UploadThing, Amazon S3, and Cloudflare R2 compared for Next.js file uploads in 2026: the egress-driven cost math, the DX tradeoffs, and which one to pick.

Updated on July 12, 2026

Three museum pedestals in a warm gallery: a managed uploader capsule, a metal vault with a toll gate, and an open jar of files flowing out freely, illustrating UploadThing, Amazon S3, and Cloudflare R2.
Three museum pedestals in a warm gallery: a managed uploader capsule, a metal vault with a toll gate, and an open jar of files flowing out freely, illustrating UploadThing, Amazon S3, and Cloudflare R2.
On this page

Quick answer (2026)

For a Next.js SaaS in 2026, pick by two things, not by the storage price: how much of the upload pipeline you want to build, and whether your files get served a lot. UploadThing is the fastest way to add uploads (a drop-in React component plus a typed server route, $10/mo flat for a 100 GB app). Cloudflare R2 is the cheapest to serve, because its egress is free ($0.015/GB-month storage, no bandwidth charge). Amazon S3 is the most powerful and the most work, and its egress bill ($0.09/GB after the first 100 GB each month) is what makes a read-heavy app expensive. All three are S3-API compatible enough that switching later is a config change, not a rewrite.

The real axis is egress and plumbing, not the per-gigabyte storage price

Every "R2 vs S3" post leads with the storage rate. For a typical Next.js SaaS that is the wrong number to stare at. Storage is cheap everywhere: a hundred gigabytes of user avatars and PDFs costs a couple of dollars a month on any of the three. What actually moves your bill, and your shipping speed, is:

  1. Egress, the price to send those files back out to users, and
  2. Who writes the upload plumbing, the presigned URL, the client component, the progress bar, the access rules.

Order the three on those two axes and the decision gets simple.

The three, quickly

UploadThing: rent the whole pipeline

UploadThing UploadThing (the pingdotgg/uploadthing repo, 5.2k GitHub stars, MIT, TypeScript, as of July 2026) is a managed uploader built for exactly this stack. You drop in a typed upload button, wire a FileRouter on the server, and uploads, storage, and a CDN are handled for you. It is the shortest path from "no uploads" to "uploads in production," and the reason it exists is that rolling your own S3 presigned-URL flow in Next.js is fiddlier than it looks.

Amazon S3: own the raw primitive

Amazon S3 Amazon S3 is the object store the other two imitate. Nothing matches its durability story, lifecycle rules, event triggers, and the depth of the AWS ecosystem around it. The cost is that you build everything (the IAM policy, the presigned URLs, the client), and you pay to send bytes out: $0.09/GB after the first 100 GB each month, with GET requests at $0.0004 per 1,000 (S3 pricing, July 2026). For a public, image-heavy app, that egress line is the whole story.

Cloudflare R2: the S3 API without the egress tax

Cloudflare R2 R2 speaks the S3 API, so the same AWS SDK code points at it with a different endpoint. The headline is egress: it is free. Storage is $0.015/GB-month, Class A (write) operations are $4.50 per million and Class B (read) operations $0.36 per million, with a free tier of 10 GB plus a million writes and ten million reads a month (R2 pricing, July 2026). You still write the upload plumbing yourself, but you stop paying every time a file is viewed.

What each actually costs in 2026

Scroll to see more

ProviderStorage /GB-moEgressFree tierYou build the upload flow?
UploadThing UploadThing$10/mo flat for 100 GB (usage tier $25/mo + $0.08/GB over 250 GB)Included2 GBNo, drop-in component
Amazon S3 Amazon S3$0.023 (first 50 TB)$0.09/GB after 100 GBLimited, 12 monthsYes
Cloudflare R2 Cloudflare R2$0.015Free10 GBYes

The gap only shows up when you plug in a real shape. Take a Next.js SaaS storing 100 GB of user files and serving 500 GB a month (images and documents loading in the browser):

  • UploadThing: the 100 GB app plan, $10/mo flat. Storage, bandwidth, and the UI are one line item.
  • Cloudflare R2: about $1.35 in storage (the first 10 GB are free) and $0 egress. Call it a dollar or two.
  • Amazon S3: about $2.30 in storage plus 400 GB of billable egress at $0.09, which is $36. Roughly $38/mo, and it climbs with every viral post.

Same files, same traffic, and S3 costs more than twenty times what R2 does, entirely because of bandwidth. UploadThing sits in the middle on price but wins on time: you are not writing a presigned-URL handler at all. Ask in r/nextjs and the recurring answer is "R2 for cost, UploadThing for speed," which matches the math above.

Where each one loses (honestly)

  • UploadThing is a managed dependency you do not control. The per-gigabyte tiers get pricier than raw R2 once you are storing terabytes, your ceiling is the plan, and you inherit its uptime and roadmap. Great for a feature, riskier as the foundation of a storage-heavy product.
  • Amazon S3 punishes public, read-heavy workloads with egress, and "just use S3" hides a real amount of IAM and presigned-URL code. It is the right answer for data lakes, compliance, and event-driven pipelines, not for serving avatars cheaply.
  • Cloudflare R2 still makes you build the upload flow (there is no Next-native component), the tooling and ecosystem are thinner than AWS, write-heavy apps pay Class A operations, and it lacks S3's deeper lifecycle and analytics features.

Which situation picks which

  • You want uploads working this afternoon and they are a feature, not the product: UploadThing.
  • Your files are public and served constantly (images, video, downloads) and you are cost-sensitive: Cloudflare R2, for the free egress.
  • You are already deep in AWS, or need lifecycle rules, compliance, or event-driven processing: Amazon S3.
  • You are on S3 today and the egress bill hurts: move to R2. Because it is S3-API compatible, it is an endpoint swap, not a rewrite.

For where file storage sits in the wider stack, this pairs with our open-source Next.js SaaS and AI starter scorecard and the data-layer call in Neon vs Supabase: your rows live in Postgres, your files live in object storage, and the two decisions rhyme, own the primitive or rent the managed wrapper.

Sources

Mara Lindqvist

Written by

Mara Lindqvist

Mara Lindqvist curates the ShipGarden gallery, road-testing open-source and source-available SaaS and AI boilerplates and the infrastructure they run on. She writes about time-to-first-deploy, cost, and vendor lock-in for founders who ship.

Frequently asked questions

Is Cloudflare R2 cheaper than Amazon S3?

For read-heavy, public workloads, yes. R2 charges nothing for egress, while S3 charges $0.09/GB after the first 100 GB each month (2026). For a 100 GB app serving 500 GB a month, R2 costs a dollar or two versus roughly $38 on S3.

Does UploadThing use S3 under the hood?

UploadThing is a managed service with its own storage and CDN. You work with its FileRouter and React components rather than an S3 bucket, trading raw control for a drop-in Next.js developer experience.

Can I migrate from S3 to R2 without rewriting code?

Largely yes. R2 implements the S3 API, so the same AWS SDK calls work against an R2 endpoint. Most migrations are a credentials-and-endpoint change plus copying the objects over.

What is the cheapest way to store files in a Next.js app in 2026?

For pure storage and serving of public files, Cloudflare R2 is usually cheapest because egress is free. For the fastest setup, UploadThing's flat plans are cheapest in engineering time.

When is Amazon S3 still the right choice?

When you need lifecycle rules, event-driven pipelines, compliance and governance controls, or you are already invested in the AWS ecosystem. S3's depth is unmatched; its egress pricing is the tradeoff.