Skip to content

Cloudflare Images and Image Resizing: When the Built-In Service Wins

Three options, three different cost curves. Picking right matters more than people think.

John Cravey with EleviFounder3 min read

There are three reasonable ways to serve optimized images for an SMB site in 2026: next/image fronted by Supabase Storage, next/image fronted by R2, or Cloudflare Images (the dedicated service). Each has a different cost model and a different operational story. Here’s how to pick.

Option 1: next/image + Supabase Storage

What it is: store originals in Supabase Storage, serve through next/image which resizes and converts on demand. The FH default for any SMB site under 100GB of images.

Cost: Supabase Pro at $25/month includes 100GB storage + 250GB egress. Most SMB sites stay inside that. next/image processing happens on your Next.js host; CPU cost is bundled with the host you’re already paying for.

Wins when: small-to-medium sites, you’re already on the Supabase + Coolify/Vercel stack, you want one integrated platform.

Option 2: next/image + Cloudflare R2

What it is: store originals in R2, serve through next/image. R2 has zero egress fees, which matters once you exceed Supabase’s included egress.

Cost: R2 storage is $0.015/GB-month. 1TB stored = $15/month. Zero egress. next/image processing still happens on your Next.js host.

Wins when: media-heavy site, you exceed Supabase’s 250GB included egress, you want predictable storage cost at scale.

Option 3: Cloudflare Images

What it is: Cloudflare’s dedicated image service. Upload originals, get back URLs with resize/transform parameters in the path. Cloudflare handles storage + transformation + delivery, all at the edge. No next/image required — just an `<img>` tag with the right URL.

Cost: $5/month per 100k images stored, $1/month per 100k images delivered. At 50k images stored, 500k requests/month, you’re paying $7.50/month. Scales linearly.

Wins when: user-uploaded photos at scale, sites with hundreds of thousands of unique images, sites where you don’t want to run your own resizing pipeline.

The decision tree

  1. Under 100GB total image storage, predictable usage? → Supabase Storage. Stay there.
  2. Heavy growth in images, going past 250GB egress? → R2 + next/image.
  3. Tens of thousands of user-uploaded images, transformation requirements (multiple sizes, watermarks, format conversion)? → Cloudflare Images.
  4. Cost-sensitive at scale with global audience? → R2 + Cloudflare Images. The combination eliminates egress fees entirely.

Cloudflare Images integration with Next

Cloudflare Images URLs look like `https://imagedelivery.net/<hash>/<image-id>/<variant>`. The `<variant>` is the resize/quality preset. You define variants in the Cloudflare dashboard (e.g., `thumbnail-300x300`, `hero-2400x1350`, `og-1200x630`) and reference them in URLs.

// app/portfolio/[slug]/page.tsx
import Image from "next/image";

export default function PortfolioItem({ params }: { params: { slug: string } }) {
  const heroId = "abc123";
  return (
    <Image
      src={`https://imagedelivery.net/${HASH}/${heroId}/hero`}
      alt=""
      width={2400}
      height={1350}
    />
  );
}

Polish and transformations

Cloudflare Images supports cropping, sharpening, format conversion, blur, brightness adjustment. We use these for: thumbnails (square crop, blur background fallback during load), social previews (1200×630 with brand overlay), responsive variants (multiple widths). The transformation cost is bundled in the delivery cost.

Migrating to Cloudflare Images from Supabase

Upload each image to Cloudflare Images via their API, get back the new image ID, store it in your database alongside the old Supabase path. Update your code to use the new URLs. Run both for a week to verify. Then delete the Supabase paths. We did this for one retail client — 45k images, $11/month savings vs. their previous Supabase egress overage. Migration time: 1 day.

When Cloudflare Images isn’t worth it

  • Under 5k images. The dashboard overhead and integration cost outweighs the benefit.
  • Images that change frequently. Cloudflare Images is optimized for upload-once-serve-many; if you re-upload often, you’re paying twice (storage + delivery) for the same content.
  • Sites that need raw image URLs (downloadable originals). Cloudflare Images doesn’t make originals accessible without an authenticated API call.

Bandwidth math at typical SMB volumes

An SMB marketing site averages 25k page views/month, 4 images per page = 100k image requests. At an optimized 80KB per image = 8GB egress/month. Well inside Supabase’s 250GB included tier. We don’t need any of the egress-saving alternatives until egress exceeds 200GB/month, which happens at roughly 12x typical SMB volume.

How this lands across FH client work

Five FH client sites use the default next/image + Supabase Storage pattern. One retail client moved to R2 + next/image for cost reasons after exceeding 600GB egress/month. One UGC-heavy client uses Cloudflare Images. The right answer depends on volume, not on what’s trendy. Book a consultation if you want a recommendation specific to your traffic pattern.

Written by
John Cravey
Founder

Founder of Frontend Horizon. Writes most of the long-form work on the FH blog.

Newer post
Supabase Performance: Indexing, Connection Pooling, and the Postgres Settings That Matter
Older post
Tool Use With Claude: Building Agents That Don’t Hallucinate Your Production Data
Keep reading

More from the blog

Cloudflare·6 min

Cloudflare DNS and CDN: The Base Configuration for Every FH Client Site

Every FH site sits behind Cloudflare. Here’s the exact configuration and why each setting is where it is.

Supabase·5 min

Supabase Storage for Marketing Sites: The Bucket-Per-Tenant Pattern

Most teams store images in their build artifact. That doesn’t scale. Supabase Storage with the right bucket layout does.

Cloudflare·4 min

Cloudflare Turnstile: The CAPTCHA That Doesn’t Make Your Users Hate You

reCAPTCHA hurts conversion. Turnstile doesn’t. Here’s the wiring that keeps your forms spam-free without the click-the-bicycles ritual.