동적 이미지 최적화 비용 비교: Cloudflare Images vs Next.js Image Optimization vs Cloudinary

웹 서비스나 모바일 앱(Next.js, Flutter 등)에서 사용자에게 고화질 이미지를 전달하기 위해 **동적 이미지 최적화(WebP/AVIF 변환, 자동 리사이징, 크롭, global CDN 딜리버리)**는 필수적이다. 하지만 서비스가 성장하고 원본 이미지 수 및 딜리버리 트래픽이 늘어남에 따라 이미지 처리 관련 청구서 비용은 개발팀에 큰 부담이 된다.
현재 업계에서 주로 사용되는 대표적인 솔루션은 Cloudflare Images, Next.js Image Optimization (Vercel), 그리고 Cloudinary 세 가지다. 세 서비스는 단순히 가격표만 다른 것이 아니라 “원본 스토리지”, “최적화 변환(Transformation)”, “CDN Egress 네트워크” 중 어느 항목에 과금 무게중심을 두느냐가 완전히 다르다.
이 글에서는 3대 이미지 최적화 플랫폼의 요금 체계를 산술적으로 분석하고, 트래픽 규모별(월 1만, 10만, 100만 건 최적화 딜리버리) 예상 비용을 산출하여 최적의 선택 기준을 제시한다.
핵심 요약
- Cloudflare Images 요금 구조: 저장소 10,000장당 $5/월 + 딜리버리(전송) 100,000건당 $1. **전 세계 CDN Egress 비용이 완전 무료($0)**라는 압도적인 이점이 있다.
- Next.js (Vercel) 요금 구조: Vercel Pro 플랜($20/월) 기준 월 1,000개 원본 이미지 최적화(Source Images)까지 기본 포함이며, 초과 시 1,000개당 $5가 과금된다. 여기에 **Vercel Egress 비용(GB당 $0.15)**이 별도로 가산된다.
- Cloudinary 요금 구조: 복잡한 크레딧(Credit) 기반 과금이다. Plus 플랜($99/월, 225 크레딧) 기준 1 크레딧 = 1,000 변환(Transformation) = 1GB Egress = 1GB 저장소로 환산된다.
- 최종 결론: 이미지 변환 딜리버리 건수와 Egress 데이터가 많은 서비스일수록 Cloudflare Images가 80%~95% 이상 저렴하다.
1. 3대 서비스 과금 방식 산술 비교
각 플랫폼의 요금 계산법 차이를 이해해야 청구서 폭탄을 피할 수 있다.
1) Cloudflare Images
- 저장 비용: 10,000개 원본 이미지당 $5.00/월
- 딜리버리 비용: 100,000회 이미지 전송당 $1.00
- Egress 비용: $0.00 (무제한 무료)
- 변환(Variant) 횟수: 이미지 업로드 시 미리 정의된 변환 규칙을 적용하며, 변환 횟수에 추가 과금이 없음.
2) Next.js Image Optimization (Vercel 배포 시)
- 원본 이미지(Source Image) 최적화 비용: Pro 플랜 ($20/월) 기준 1,000개 원본 이미지 무료 포함. 초과 1,000개 원본당 $5.00/월 (요청된 쿼리 변환 수와 상관없이 원본 URL 개수로 카운트).
- 네트워크 Egress 비용: GB당 $0.15 (Vercel 기본 Egress 요금 적용)
3) Cloudinary
- 크레딧 요금제: Free 플랜 25 크레딧/월 제공. Plus 플랜 $99/월 (225 크레딧 포함).
- 크레딧 소진 기준: 1 Credit = 1,000회 이미지 변환 OR 1GB Egress 데이터 전송 OR 1GB 저장 공간.
- Egress 및 변환 요구량이 많아질수록 크레딧이 대량으로 차감된다.
2. 트래픽 규모별 월간 예상 비용 실측 비교
아래 표는 평균 원본 이미지 10,000장, 평균 최적화 이미지 용량 150KB 조건에서 월간 최적화 이미지 딜리버리 건수 및 트래픽에 따른 비용 비교이다.
| 항목 및 트래픽 규모 | Cloudflare Images | Next.js Image Optimization (Vercel) | Cloudinary |
|---|---|---|---|
| 소규모 (월 10만 건 전송 / 15GB Egress) | $6.00 ($5 저장 + $1 딜리버리) |
$65.00 ($20 Pro + $45 소스이미지 초과) |
$0.00 ~ $99.00 (Free 크레딧 범위 내) |
| 중규모 (월 50만 건 전송 / 75GB Egress) | $10.00 ($5 저장 + $5 딜리버리) |
$76.25 ($20 Pro + $45 소스 + $11.25 Egress) |
$99.00 (Plus 플랜 225 크레딧) |
| 대규모 (월 300만 건 전송 / 450GB Egress) | $35.00 ($5 저장 + $30 딜리버리) |
$132.50 ($20 Pro + $45 소스 + $67.50 Egress) |
$299.00+ (Advanced 플랜 이상) |
| 초대형 (월 1,000만 건 전송 / 1.5TB Egress) | $105.00 ($5 저장 + $100 딜리버리) |
$290.00 ($20 Pro + $45 소스 + $225 Egress) |
$800.00+ (Custom Enterprise) |
3. Next.js에서 Cloudflare Images 커스텀 로더 구현
Next.js의 기본 next/image 최적화 로직은 Vercel Serverless Function을 실행하므로 비용이 비싸다. 이를 Cloudflare Images의 융통성 있는 딜리버리 URL로 연결하는 Custom Loader를 작성하면 비용을 크게 절감할 수 있다.
1) Next.js 커스텀 로더 (cloudflareLoader.ts)
// cloudflareLoader.ts
export default function cloudflareLoader({
src,
width,
quality,
}: {
src: string;
width: number;
quality?: number;
}) {
const params = [`width=${width}`, `quality=${quality || 75}`, `format=auto`].join(',');
// Cloudflare Images Flexible Variants URL 구조
const accountHash = process.env.NEXT_PUBLIC_CLOUDFLARE_ACCOUNT_HASH;
// 외부 URL인 경우 Flexible Variant(Resizing) 이용 예시
return `https://imagedelivery.net/${accountHash}/${src}/w=${width},q=${quality || 75}`;
}
2) next.config.js 설정
/** @type {import('next').NextStyle}.NextConfig */
const nextConfig = {
images: {
loader: 'custom',
loaderFile: './cloudflareLoader.ts',
},
};
module.exports = nextConfig;
4. Flutter 앱에서의 적용 코드 (CachedNetworkImage)
Flutter 모바일/웹 앱에서 Cloudflare Images의 융통성 있는 동적 리사이징 URL을 생성해 사용하는 방법도 매우 간편하다.
import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
class CloudflareOptimizedImage extends StatelessWidget {
final string imageId;
final double width;
final double height;
const CloudflareOptimizedImage({
super.key,
required this.imageId,
required this.width,
required this.height,
});
String _buildCloudflareImageUrl(String id, int targetWidth) {
const accountHash = "YOUR_CLOUDFLARE_ACCOUNT_HASH";
// Cloudflare Flexible Variant URL
return "https://imagedelivery.net/$accountHash/$id/w=$targetWidth,format=auto";
}
@override
Widget build(BuildContext context) {
final targetPixelWidth = (width * MediaQuery.of(context).devicePixelRatio).toInt();
final imageUrl = _buildCloudflareImageUrl(imageId, targetPixelWidth);
return CachedNetworkImage(
imageUrl: imageUrl,
width: width,
height: height,
fit: BoxFit.cover,
placeholder: (context, url) => Container(color: Colors.grey[200]),
errorWidget: (context, url, error) => const Icon(Icons.error),
);
}
}
결론: 내 서비스에 맞는 최적의 선택은?
- Cloudflare Images: 트래픽과 이미지 전송량이 많거나, Egress 비용 부담을 제로로 만들고 싶을 때 독보적으로 경제적이다.
- Next.js Image Optimization (Vercel): 원본 이미지 종류가 적고(1,000개 이내) 별도 외부 이미지 서버를 세팅하기 귀찮은 초소규모 프로젝트에 적합하다.
- Cloudinary: 딥러닝 기반 배경 제거, 자동 스마트 크롭, 복잡한 비디오/이미지 캔버스 필터링 등 고도화된 리터칭 기능이 필요할 때 적합하다.
대부분의 일반적인 웹/앱 동적 이미지 최적화 및 딜리버리 유스케이스에서는 Cloudflare Images가 비용과 성능 모든 면에서 압도적인 가성비를 자랑한다.