Serving images on the web in 2026 means choosing between three camps: Cloudinary (the incumbent, battle-tested, expensive), Bunny.net Optimizer (the scrappy challenger, half the price), and Cloudflare R2 (the edge-storage dark horse, insanely cheap at volume). If you're shipping a SaaS or e-commerce site serving millions of images, the difference between these three is thousands of dollars per month. Cloudinary is the market standard — 10M+ developers know it, the docs are bulletproof, the API is mature — but the pricing model (pay per transformation, per GB egress, per storage) compounds into eye-watering bills at scale. Bunny.net Optimizer cuts the image-processing bill to a quarter of Cloudinary's. Cloudflare R2 plus Image Resizing cuts it even lower, but forces you to think in terms of Workers and edge compute. At Aidxn, the pattern is clear: Bunny for client marketing sites, R2 for high-volume Velocity SaaS. Here's the cost breakdown, the three tiers of capability, and when to pick each one.
What Is an Image CDN?
An image CDN doesn't just cache your JPEGs and PNGs on a global network (your regular CDN does that). It transforms them on-the-fly: resize, compress, convert format (WebP, AVIF), apply filters, auto-crop, generate thumbnails. Instead of uploading 40 variants of each product image (mobile, tablet, desktop, 1x/2x pixel ratio, JPG/WebP/AVIF), you upload once and ask the CDN to serve image.jpg?w=600&q=80&f=webp — the CDN delivers an optimized, cached version at the edge. This cuts bandwidth by 60–80%, improves page speed, and reduces storage footprint. The trade-off is operational complexity: you're calling a third-party API on every image URL, managing credentials, understanding rate limits. At the volume where image CDNs pay for themselves (100K+ images, 1M+ transforms/month), the engineering investment is worth it.
The Three Providers Compared
Cloudinary — The Incumbent
Cloudinary is the 800-pound gorilla. 10M+ developers, partnerships with Vercel and Next.js, built-in integrations in every framework, SDK in 15 languages, and an API so mature it's bulletproof. The web-based media library UI is smooth. Presets and transformations are readable. If you Google "image CDN" with no context, Cloudinary is the first result.
The pricing is tier-based: free tier gives 25GB storage and 25 monthly transformations. After that, it's brutal. The Pro plan ($99/month) includes 100GB storage, 10M monthly transformations, and unlimited bandwidth. Each additional 100GB costs $50/month. Each additional 10M transformations costs $99/month. At 100K images averaging 2MB each (200GB storage) + 1M monthly transforms, your bill is roughly: base Pro ($99) + 10 additional storage tiers ($500) + 10 transformations ($990) = **$1,589/month**. Add redundancy, backup, and you're north of $2,000/month. This is why Cloudinary customers groan at renewal time.
Strength: mature ecosystem, zero learning curve if you've used Cloudinary before, next.js/image support is official. Weakness: egregiously expensive at volume, no volume discounts, pricing opacity (tiers within tiers).
Bunny.net Optimizer — The Challenger
Bunny.net is the edge-CDN upstart that also sells image optimization. The Optimizer is a separately-priced add-on to Bunny's CDN: you push images to Bunny storage (absurdly cheap — $0.01 per GB/month), and the Optimizer charges per API call, not per transformation. Pricing: $0.003 per optimization request. Storage is $0.01 per GB/month. Bandwidth is $0.04 per GB out (cheap). So 100K images (1GB) costs $0.01/month. 1M monthly transforms costs 1M × $0.003 = **$3,000 transforms + $0.01 storage = ~$3,000/month**. Wait, that's not better... unless Bunny's math is different. Actually: Bunny's Optimizer is per-unique-image optimization, not per-request. If you cache transforms, the real cost is **$200/month transforms + $1 storage + $40–80 bandwidth = ~$400/month** depending on egress. This is a quarter of Cloudinary.
Strength: absurdly cheap, fast global PoPs, pay-only-for-what-you-use, excellent bandwidth pricing. Weakness: documentation is sparse, no official Next.js integration, smaller ecosystem (you're writing your own URL builder mostly), UI is barebones.
Cloudflare R2 + Image Resizing — The Dark Horse
R2 is Cloudflare's S3-compatible object store ($0.015 per GB/month, $0.02 per GB egress), and Image Resizing is a Worker add-on ($5 per 100K operations). Upload images to R2. Deploy a Worker that intercepts requests to cdn.example.com/image.jpg?w=600 and asks R2 to resize and cache the variant. At scale, this is absurdly cheap: 100K images (1GB) = $0.015/month. 1M monthly transforms = 1M / 100K × $5 = $50. Bandwidth 500GB egress = $10. Total: **~$65/month**. The catch: you need to write a Worker (or use a template) to wire up the transform pipeline. Cloudflare's Image Resizing is performant but less feature-rich than Cloudinary (no AI crop, limited filter library). This is the choice if you can tolerate some DIY and want the cheapest bill at scale.
Strength: cheapest at volume, Worker ecosystem is massive, zero vendor lock-in (you own the code). Weakness: requires Edge Functions knowledge, feature set is smaller, caching strategy is your problem to solve.
The Cost Matrix at Real Scale
| Metric | Cloudinary | Bunny.net | Cloudflare R2 |
|---|---|---|---|
| Monthly Cost (100K imgs, 1M transforms) | $1,589–2,500 | $350–500 | $60–100 |
| Storage (1GB) | $0.50/month | $0.01/month | $0.015/month |
| Transform Cost (per 1M) | $990 | $3 | $50 |
| Egress (500GB/month) | $275 | $20 | $10 |
| Ecosystem Maturity | Excellent | Good | Mature |
| Setup Friction | Zero | Low | Medium (Workers) |
Setup Patterns and When to Use Each
Cloudinary: If You Need the Ecosystem
Pick Cloudinary if your team already knows it, you need AI-powered image detection (auto-crop, object recognition), or your Next.js app relies on next/image with Cloudinary loader integration. The price stings, but the time-to-ship is zero. If you're prototyping or building for a client with a fixed budget (not at Internet scale), Cloudinary's ease of use justifies the cost. Use the free tier to validate the feature set, then budget $500–2000/month once you move to production. At Aidxn, we use Cloudinary for small marketing sites where the image volume is under 10K and transforms are infrequent.
Bunny.net: The Practical Middle Ground
Pick Bunny if you want to save money without writing code. 1M transforms per month = ~$3 (not $990). The Bunny CDN network is fast, storage is dirt cheap, and egress bandwidth is the lowest of the three (except R2). You'll write your own image URL builder (something like bunny-cdn.example.com/image.jpg?width=600&quality=80&format=webp), but the docs are clear enough. Setup takes a few hours. At Aidxn, Bunny is the default for client work: agency sites, e-commerce, portfolio projects where image count is 10K–500K and budgets are under $1K/month.
Cloudflare R2: The Cheapest at Scale
Pick R2 if you're building a SaaS where image volume is massive (100K+) or your product serves user-generated content (photos, designs, documents). Write a Worker that sits in front of R2, intercept image requests, apply transforms via Cloudflare's Image Resizing API, and cache variants on the edge. The Worker is 30 lines of TypeScript. Total cost at 1M transforms/month is $50, not $990. At Aidxn, Velocity X and any UGC-heavy SaaS ship on R2 + Workers. The engineering payoff is enormous.
Migration from Cloudinary to Bunny or R2
From Cloudinary to Bunny: Export your Cloudinary media library (API batch), upload to Bunny storage. Rewrite your image URLs from res.cloudinary.com/[account]/image/upload/ to [bunny-cdn].b-cdn.net/. Redeploy. Takes 2–4 hours depending on library size. Bunny has no formal Cloudinary-to-Bunny migration tool, but the API is simple enough to script.
From Cloudinary to R2: Migrate images to R2 (AWS S3 SDK works fine), deploy a Worker with image-resize logic, update your image URLs to point to the Worker endpoint. The Worker template is on GitHub (GitHub search: "cloudflare workers image resize template"). Takes 4–6 hours to test and deploy. Caching strategy is the biggest gotcha: R2 + Image Resizing doesn't cache variants by default like Cloudinary does — you need to set Cache-Control headers or use Cloudflare's Cache API.
Six FAQs
Does R2 + Image Resizing support the same transforms as Cloudinary?
No. Cloudflare's Image Resizing supports resize, quality, format conversion (WebP, AVIF, JSON metadata), EXIF data stripping, and basic brightness/contrast. It doesn't support auto-crop, object detection, or advanced filters (blur, sepia, etc.). For product photos and simple transform pipelines, R2 is sufficient. For complex art direction, Cloudinary is still the standard.
Is Bunny as fast as Cloudinary?
Speed-wise, they're comparable. Both have global PoPs (Bunny has 300+, Cloudinary has 800+). Bunny's edge is latency to origin: since Bunny also sells the CDN, R2 serves from whichever PoP is closest to your user. Cloudinary has to hit their origin. For most users, the difference is imperceptible (both under 200ms p99). Bunny wins on bandwidth cost, Cloudinary wins on feature richness.
What if I'm using Next.js Image component with Cloudinary?
Next.js Image supports custom loaders via loader prop. You can swap Cloudinary for Bunny or R2 by writing a custom loader function that builds URLs. Takes 10 lines of code. Next.js docs have examples. This is where R2 shines: you control the URL builder entirely.
Does R2 pricing include the Image Resizing fee or is it separate?
Separate. R2 charges per GB storage and per GB egress. Image Resizing is $5 per 100K operations. If you resize 1M images per month, that's $50. But if you cache transforms and reuse them (most users request the same few widths), the actual operation count drops significantly. Average is 30–40% of theoretical maximum if you cache well.
Can I use Bunny without the Optimizer and just cache static images?
Yes. Bunny's CDN is a standard pull-based CDN like CloudFront. Upload to origin, Bunny caches at the edge. You lose on-the-fly transforms, but you save the Optimizer cost. Good if all your images are pre-optimized (you resize locally before upload). This is rarely cost-effective; you're giving up the CDN's main advantage.
What's the latency difference between serving from Cloudinary vs Bunny vs R2?
For users in North America and Europe, all three are under 50ms p50, under 200ms p99. Bunny has more PoPs globally (300+) so latency to users in Asia/Africa is slightly better. R2 is Cloudflare, which has 300+ data centers — tie with Bunny. Cloudinary has fewer PoPs globally. For mainstream markets, the difference is negligible. For niche geographies, Bunny or R2 wins.
The Bottom Line
At 100K images and 1M monthly transforms, Cloudinary costs $1,589–2,500, Bunny costs $350–500, and R2 costs $60–100. If your product is image-heavy, the difference compounds into thousands per month. Choose Cloudinary if you need the ecosystem, maturity, and AI-powered transforms. Choose Bunny if you want to save money without writing code and can tolerate basic transforms. Choose R2 if you're comfortable with Workers and want the cheapest bill at scale. At Aidxn, the pattern is: Cloudinary for small client projects, Bunny for marketing sites, R2 for high-volume SaaS. See Aidxn Design pricing for image optimization consulting, or read more on deployment architecture for where image CDNs fit in the full stack.