The bill that scales with success is the one to avoid
Most object storage charges you every time data leaves it. That is fine until something gets popular, and then the egress line on the invoice grows with your traffic, which is to say it grows fastest exactly when you can least afford a surprise. Zero egress storage breaks that link.
What R2 changes
Cloudflare R2 is S3 compatible object storage with no egress fees. You pay for what you store and for the operations you perform, not for the bytes your users download. For an image heavy product serving a market on slow and expensive connections, that is not a small optimization, it is the difference between a viable unit cost and a broken one.
Writing to it from a serverless function
You do not need the heavy AWS SDK, which can be slow to load in a serverless runtime. A small signer is enough to make an authenticated request.
import { AwsClient } from "aws4fetch";
const r2 = new AwsClient({
accessKeyId: process.env.R2_ACCESS_KEY_ID!,
secretAccessKey: process.env.R2_SECRET_ACCESS_KEY!,
region: "auto",
service: "s3",
});
await r2.fetch(`${endpoint}/${bucket}/${key}`, {
method: "PUT",
body: bytes,
headers: { "Content-Type": "image/png" },
});
Serve it through an image pipeline
Storing the original once and transforming it on read is the pattern that keeps both the storage bill and the bytes on the wire small. Put an image CDN in front of the bucket, request the width you actually need, and let the CDN negotiate a modern format per device. On this platform that turned a near megabyte source image into a few tens of kilobytes for a phone, with no second copy stored anywhere.
The principle
Pay for storage, not for popularity. When the cost of serving an asset does not rise with the number of people who view it, you can build for reach without flinching at the invoice.
