Cloudinary Alternatives for App Images (Cheaper Options)

For most apps, the best Cloudinary alternative is the one closest to where the images already live. If users upload avatars and photos into your backend's storage, resizing in that same storage (StitchDB or Supabase) avoids a second vendor. If you need a dedicated image CDN with more features, ImageKit and Cloudflare Images are cheaper than Cloudinary at small and medium volumes. If you want zero per-image fees and can run a server, imgproxy is open source.

Cloudinary is a full media platform: transformations, video, AI cropping, a digital asset manager. Plenty of apps use one percent of that, mostly "make this upload 200 pixels wide and WebP". This guide is for them.

#How Cloudinary charges

Cloudinary bills in credits. As of November 2026, its pricing page lists:

PlanPriceCredits per month
Free$025
Plus$99/mo ($89/mo yearly)225
Advanced$249/mo ($224/mo yearly)600
EnterpriseCustomCustom

One credit is 1,000 transformations, or 1 GB of managed storage, or 1 GB of image bandwidth (or 2 GB of video bandwidth on paid plans). You can mix them. So the free plan is, for example, 10 GB storage + 10 GB bandwidth + 5,000 transformations.

Credits are flexible but make costs hard to predict, because storage, delivery and new sizes all draw from the same pool.

#What a typical app needs

Before comparing, write down your numbers. A social app with 20,000 users might need:

  • 25,000 stored images (avatars, posts), about 15 GB
  • 4 sizes per image (thumbnail, list, detail, full)
  • 50-150 GB of image delivery a month
  • WebP or AVIF output for browsers that accept it

The transformations are mostly one-time per size, if the service caches results. That's the key question for every option below: is a cached render free, or does each delivery count?

#Cloudinary alternatives compared

OptionFree tier (Nov 2026)Paid pricingCached rendersWhere originals live
StitchDB Storage1,000 transformations/mo, 1 GB storagePro $15.99/mo: 25,000 transformations, 100 GBPublic renders cached, don't countYour project's buckets (EU)
Supabase StorageNot on FreePro and up: 100 origin images, then $5 per 1,000See Supabase docsYour project's buckets
ImageKit20 GB bandwidth, 3 GB storageLite $9/mo: 40 GB bandwidth, 10 GB storageCDN deliveryImageKit storage (see docs for external origins)
Cloudflare Images5,000 unique transformations/mo$0.50 per 1,000 unique transformationsUnique transformations billed once a monthCloudflare or any origin
imgproxy (open source)FreeYour servers; Pro version availableAdd your own CDNAny storage you point it at

#StitchDB Storage: resize where you store

StitchDB is a hosted backend (dedicated Postgres, Auth, APIs, Realtime, Edge Functions) with Storage built in. Any image in a bucket can be served at another size, fit, format or quality by changing its URL. Images are resized on your project's server and public renders are cached there for an hour, per size and format; a cached image doesn't count toward your monthly transformations. The X-Cache: HIT header shows it.

With the SDK:

JavaScript
const { data } = stitchdb.storage.from('avatars').getPublicUrl('ann.png', {
  transform: { width: 200, height: 200, resize: 'cover', quality: 75 },
})
// https://<project-ref>.p.stitchdb.com/storage/v1/render/image/public/avatars/ann.png?width=200&height=200&resize=cover&quality=75

Options from the image resizing docs:

  • width, height: 1 to 2,000 pixels; give one to keep the aspect ratio.
  • resize: cover, contain or fill.
  • quality: 20 to 100, default 80.
  • format: webp, avif or origin; without it, browsers that accept WebP get WebP.
  • Sources up to 25 MB and 16.8 megapixels; PNG, JPEG, WebP, GIF, AVIF, HEIC, BMP and TIFF are read.

Monthly transformations per project as of November 2026: 1,000 on Free, 25,000 on Pro, 100,000 on Scale, 1,000,000 on Enterprise. At the limit, resized URLs return 429 until next month while originals keep working.

Private images work too, through signed render URLs or with the user's token checked against your storage policies. Those renders are made on every request (they're private), so each one counts. Cache them in the app if you show them often.

Where it falls short: no AI cropping, face detection, overlays or video transformation. Width and height cap at 2,000 pixels. Servers are in the EU, so for a worldwide audience you may want a CDN in front of public images. If you need those features, a dedicated image service is the better tool.

#Supabase Storage

Supabase Storage has image transformations on Pro and above. As of November 2026, Pro includes 100 origin images, then $5 per 1,000 origin images; widths and heights go up to 2,500 pixels and files up to 25 MB. It's billed by origin image, not by render, which suits apps with few images and many sizes.

#ImageKit

ImageKit is a dedicated image and video CDN. Its free plan includes 20 GB of bandwidth and 3 GB of storage; Lite is $9/month with 40 GB bandwidth and 10 GB storage, then $0.50 per GB bandwidth. A good straight swap for Cloudinary; check its docs for connecting your existing storage as an origin.

#Cloudflare Images

Cloudflare Images charges by unique transformation: 5,000 a month free, then $0.50 per 1,000. Storing images with Cloudflare costs $5 per 100,000 images and delivery $1 per 100,000 images (pricing). On the free plan, transformations beyond the limit return an error instead of a bill. Strong if you're already on Cloudflare.

#imgproxy

imgproxy is an open-core, self-hosted image server: you pass processing options in the URL and it resizes on the fly from your own storage. The open-source edition supports JPEG, PNG, GIF, WebP, AVIF and JPEG XL. You run it (often as a container) and put a CDN in front. No per-image fees, but you own uptime and scaling.

#Picking by situation

  • Avatars and user photos in a mobile or web app: resize in your backend storage. StitchDB if you want it on every plan; Supabase if you're on its Pro plan.
  • E-commerce catalog with heavy traffic worldwide: ImageKit or Cloudflare Images, for global CDN delivery.
  • Marketing site and media library with editors: Cloudinary is still the most complete, and its asset manager matters here.
  • Cost-sensitive with ops capacity: imgproxy behind a CDN.

#Moving off Cloudinary

  1. Export originals. Download the source files from Cloudinary (see its docs for bulk export options).
  2. Upload to the new storage. For StitchDB, the S3 endpoint works with rclone or the aws cli for bulk copies.
  3. Map URLs. Cloudinary URLs encode transformations in the path (w_200,h_200,c_fill). Write a small helper in your app that turns your sizes into the new URL format, then replace URL building in one place.
  4. Keep old URLs alive during the switch, or redirect them, because old URLs may be cached in apps and e-mails.

A helper that keeps sizes in one place:

TypeScript
const SIZES = { thumb: 96, list: 320, detail: 960 } as const

export function imageUrl(path: string, size: keyof typeof SIZES) {
  const { data } = stitchdb.storage.from('photos').getPublicUrl(path, {
    transform: { width: SIZES[size], quality: 75 },
  })
  return data.publicUrl
}

More on uploads and buckets in File uploads and storage for web and mobile apps, and if your files are on Firebase today, see Firebase Storage alternatives.

#FAQ

#What is the cheapest Cloudinary alternative?

For low volumes, free tiers: ImageKit (20 GB bandwidth), Cloudflare Images (5,000 transformations) and StitchDB (1,000 transformations, cached renders free). For zero per-image fees, self-hosted imgproxy.

#Is Cloudinary's free plan enough?

It includes 25 credits a month as of November 2026, for example 10 GB storage, 10 GB bandwidth and 5,000 transformations combined. Many small apps fit.

#Does StitchDB support AVIF?

Yes. Set format: 'avif', or leave it out and browsers that accept WebP get WebP.

#Do cached image renders count toward StitchDB limits?

Cached public renders don't count toward transformations. They still count as egress, like any download.

Resize uploads without another vendor: start free on StitchDB.