Building Yaldi.chat: Why Cloudflare R2 + CDN Beat S3 + CloudFront
Images are deceptively expensive. They’re easy to underestimate because each one is small, static, and simple. But at scale—especially when you’re serving user-generated content into a real-time chat environment—image delivery becomes the dominant cost and performance factor in the entire system.
For Yaldi, emotes are not large assets. They’re small files, fetched frequently, cached aggressively, and rendered constantly. That specific shape of workload heavily influenced the decision to use Cloudflare R2 + Cloudflare CDN instead of the more traditional Amazon S3 + CloudFront combination.
The Shape of the Yaldi Image Workload
Before comparing services, it’s important to understand the actual workload—because this decision is extremely workload-sensitive. Yaldi’s image traffic looks like this:
- Very small files (emotes, not photos or videos)
- High request volume relative to total bytes transferred
- Read-heavy (writes happen only on upload or version change)
- Highly cacheable (same URLs requested repeatedly)
- Latency-sensitive (chat rendering feels slow if images lag)
This is not a “large object storage” problem. It’s a “many tiny objects, fetched constantly” problem.
The Default Choice: S3 + CloudFront
On AWS, the obvious choice is Amazon S3 backed by CloudFront. It’s battle-tested, powerful, and flexible. It’s also optimized for a very broad range of use cases—which means you often pay for flexibility you don’t actually need.
Where S3 + CloudFront Shine
- Large objects
- Predictable regional traffic
- Deep AWS ecosystem integration
- Complex origin behaviors
None of those are bad things. They’re just not the dominant requirements for Yaldi.
The Cost Problem with Small Files
When files are small, request pricing matters more than bandwidth pricing. With S3 + CloudFront, you pay:
- Per-request fees at S3 (for cache misses)
- Per-request fees at CloudFront
- Data transfer (often minor for small assets)
For tiny images, bandwidth costs stay low—but request counts explode. Each chat message can trigger multiple image fetches across many clients.
This is where Cloudflare R2 fundamentally changes the economics.
Why Cloudflare R2 Fits This Workload
Cloudflare R2 is object storage designed specifically to remove one of the biggest pain points in traditional cloud storage: egress fees.
1) Zero egress fees to the CDN
With R2, data served through the Cloudflare CDN does not incur egress charges. For image-heavy workloads with global distribution, this is a massive advantage.
This alone changes how aggressively you can cache and how comfortable you can be serving assets globally.
2) Request economics favor small objects
R2 pricing is structured in a way that makes high request counts far less punishing than S3 + CloudFront. When your average object is measured in kilobytes, this matters more than raw throughput numbers.
3) Storage is cheap and boring
Once uploaded, emotes rarely change. R2 provides durable storage without the mental overhead of lifecycle rules, replication strategies, or tiering decisions.
CDN Behavior: Why Cache Hit Ratio Is Everything
For Yaldi, the ideal request is one that never reaches the origin. Cloudflare’s CDN makes this easy to achieve:
- Global edge presence close to users
- Aggressive caching by default
- Simple cache rules
- Low-latency TLS termination
Most emote URLs are immutable or versioned. That allows for long cache lifetimes and extremely high cache hit ratios. In practice, once an emote is “hot,” it is served almost entirely from the edge.
Speed: Why Latency Matters More Than Throughput
When rendering chat, users don’t care about throughput. They care about perceived latency. An emote that appears 300ms late feels broken—even if the total data transferred is tiny. Cloudflare’s edge network reduces:
- DNS lookup time
- TLS handshake latency
- Geographic distance to the cache
For small files, those fixed costs dominate total request time. Serving from an edge node close to the user is far more impactful than optimizing backend throughput.
Image Resizing at the Edge
Yaldi uses Cloudflare’s image resizing capabilities to generate multiple sizes of the same emote on demand. This avoids:
- Pre-generating dozens of variants
- Storing redundant files
- Running image processing in the backend
The CDN becomes both the delivery layer and the transformation layer—exactly where image work belongs.
Operational Simplicity Matters
Beyond cost and performance, R2 + Cloudflare CDN reduces operational surface area. There’s no:
- Separate origin access identity setup
- Complex CloudFront distribution management
- Per-region tuning
- Surprise egress billing
Objects live in R2. They’re served through Cloudflare. That’s the whole mental model.
When S3 + CloudFront Is Still the Right Choice
S3 + CloudFront remains excellent if:
- You serve large media files
- You need deep AWS-native integration
- Your traffic is predictable and regional
- You already operate heavily within AWS
For Yaldi’s workload—many tiny images, fetched constantly, from all over the world—the economics and performance characteristics tilt heavily toward Cloudflare.
The Practical Takeaway
Cloudflare R2 + CDN is not universally better than S3 + CloudFront. It is, however, extremely well suited for workloads dominated by:
- Small, immutable assets
- High request counts
- Global distribution
- Latency-sensitive rendering
Yaldi’s emotes fit that profile perfectly.
Comments
No comments yet.
Leave a comment