effidevFlutter · Cloudflare 엣지 · 클라우드 비용 최적화
한국어

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

동적 이미지 최적화 비용 비교: Cloudflare Images vs Next.js 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

2) Next.js Image Optimization (Vercel 배포 시)

3) Cloudinary


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),
    );
  }
}

결론: 내 서비스에 맞는 최적의 선택은?

  1. Cloudflare Images: 트래픽과 이미지 전송량이 많거나, Egress 비용 부담을 제로로 만들고 싶을 때 독보적으로 경제적이다.
  2. Next.js Image Optimization (Vercel): 원본 이미지 종류가 적고(1,000개 이내) 별도 외부 이미지 서버를 세팅하기 귀찮은 초소규모 프로젝트에 적합하다.
  3. Cloudinary: 딥러닝 기반 배경 제거, 자동 스마트 크롭, 복잡한 비디오/이미지 캔버스 필터링 등 고도화된 리터칭 기능이 필요할 때 적합하다.

대부분의 일반적인 웹/앱 동적 이미지 최적화 및 딜리버리 유스케이스에서는 Cloudflare Images가 비용과 성능 모든 면에서 압도적인 가성비를 자랑한다.