S3와 R2를 다시 비교해보니, 저장비보다 CDN 경로가 더 중요했습니다
이 글의 가격과 제품 조건은 2026년 8월 4일 공식 문서 기준입니다.
처음에는 AWS S3와 Cloudflare R2의 저장 단가를 나란히 놓고 비교하려고 했습니다. R2 Standard는 월 GB당 0.015달러이고 인터넷 전송 비용이 없습니다. S3는 리전과 스토리지 클래스에 따라 가격이 달라지고 인터넷으로 직접 내보내는 데이터에는 비용이 붙습니다. 여기까지만 보면 답은 R2처럼 보였습니다.
그런데 공식 문서를 다시 맞춰보면서 비교 단위부터 잘못 잡았다는 걸 알았습니다. 실제 서비스에서 사용자는 저장소에 직접 접근하기보다 CDN을 거쳐 이미지와 동영상을 받습니다. 그렇다면 비교해야 할 것은 S3 대 R2가 아니라 아래 두 경로입니다.
S3 → CloudFront 글로벌 엣지 → 사용자
R2 → Cloudflare Cache 글로벌 엣지 → 사용자저장소만 비교하면 비용의 절반만 보게 됩니다. 원본까지 도달하는 요청 수, 캐시 적중률, 사용자에게 전달되는 데이터양을 같이 봐야 했습니다.
저장 단가만 보면 R2가 단순합니다
R2 Standard의 현재 가격 구조는 비교적 읽기 쉽습니다.
| 항목 | R2 Standard |
|---|---|
| 저장 | 월 $0.015/GB |
| Class A 작업 | 100만 회당 $4.50 |
| Class B 작업 | 100만 회당 $0.36 |
| 인터넷 전송 | 무료 |
| 월 무료 구간 | 저장 10GB, Class A 100만 회, Class B 1,000만 회 |
Class A는 쓰기와 목록 변경에 가까운 작업이고, Class B는 읽기에 가까운 작업입니다. Cloudflare는 사용량을 다음 청구 단위로 올림하므로 작은 차이가 다음 100만 회 구간으로 넘어갈 수도 있습니다. 연결한 다른 유료 서비스의 비용까지 면제되는 것도 아닙니다. 자세한 숫자는 Cloudflare R2 공식 가격표에서 확인할 수 있습니다.
S3는 저장 클래스와 리전에 따라 가격이 달라집니다. 저장, 요청, 검색, 인터넷 전송, 복제와 분석 기능을 따로 계산합니다. 인터넷에서 S3로 들어오는 데이터와 같은 리전의 AWS 서비스로 보내는 데이터는 대부분 무료지만, S3에서 인터넷으로 직접 나가는 데이터에는 무료 구간 이후 비용이 발생합니다. 반면 S3에서 CloudFront로 보내는 데이터 전송은 무료입니다. AWS S3 공식 가격표
이 차이 때문에 S3를 공개 파일 서버처럼 직접 노출한 비용과 CloudFront 원본으로 사용한 비용은 전혀 다르게 계산해야 합니다.
R2의 egress 무료가 요청 무료는 아니었습니다
제가 R2에서 놓치기 쉬웠던 부분은 요청 횟수였습니다. 전송 비용이 0달러여도 원본 읽기가 계속 발생하면 Class B 비용이 쌓입니다.
Cloudflare가 공개한 예시가 꽤 구체적입니다. 평균 100KB 파일 10만 개를 저장하고 하루 1,000만 번씩 읽으면 저장 용량은 무료 구간에 들어갑니다. 하지만 한 달에 2억9천만 건이 유료 Class B 작업으로 계산돼 약 104.40달러가 발생합니다. R2 자산 호스팅 계산 예시
작은 파일을 매우 자주 읽는 서비스에서는 데이터양보다 요청 수가 비용을 결정합니다. 그래서 R2를 선택해도 Custom Domain과 캐시 정책을 붙여 원본 요청을 줄이는 작업이 필요합니다.
CloudFront 정액제를 보고 계산이 다시 바뀌었습니다
이번 비교에서 가장 크게 달라진 부분은 CloudFront 정액제였습니다. 예전 방식대로 CloudFront의 GB당 종량제만 떠올리면 R2의 무료 egress가 압도적으로 보입니다. 현재는 다음과 같은 정액 플랜도 선택할 수 있습니다.
| 플랜 | 월 가격 | 월 전송 기준 | 요청 기준 | S3 Standard 크레딧 |
|---|---|---|---|---|
| Free | $0 | 100GB | 100만 건 | 5GB |
| Pro | $15 | 50TB | 1,000만 건 | 50GB |
| Business | $200 | 50TB | 1억2,500만 건 | 1TB |
| Premium | $1,000 | 50TB | 5억 건 | 5TB |
CloudFront CDN뿐 아니라 WAF, DDoS 보호, Route 53과 일부 로그 비용이 포함됩니다. 특히 월 15달러인 Pro의 전송 기준이 50TB라는 점은 S3는 트래픽 때문에 무조건 비싸다는 판단을 다시 보게 만들었습니다. AWS 플랜·가격 안내, CloudFront 정액제 기능 안내
물론 50TB가 아무 조건 없는 무제한 약속은 아닙니다. 플랜은 CloudFront 배포 하나와 루트 도메인 하나를 기준으로 하고, 등급마다 캐시·보안 기능에 차이가 있습니다. 사용량 기준을 여러 달 지속해서 크게 넘으면 AWS가 더 적거나 먼 엣지 위치를 사용하도록 전달 성능을 조정할 수 있습니다. 종량제와 정액제 중 어느 쪽이 맞는지는 요청 수와 필요한 기능까지 넣어 계산해야 합니다.
글로벌 엣지는 모든 파일의 영구 복제본이 아닙니다
글로벌 엣지 스토리지라는 표현도 조심해서 볼 필요가 있습니다. 모든 파일이 전 세계 모든 엣지에 영구 저장된다는 뜻은 아닙니다.
R2는 요청을 가까운 Cloudflare 게이트웨이에서 받고, 오브젝트는 버킷 위치에 해당하는 분산 스토리지 인프라에 저장합니다. 캐시를 활성화하면 자주 읽는 콘텐츠를 가까운 엣지에서 바로 전달하지만, 캐시에 없는 파일은 원본 저장 위치에서 가져옵니다. Cloudflare R2 아키텍처
R2 버킷은 기본적으로 비공개입니다. Cloudflare Cache를 사용하려면 자신이 관리하는 Custom Domain을 연결해야 합니다. 개발용 r2.dev 주소는 캐시, WAF, 봇 관리 기능을 지원하지 않습니다. R2 캐시 활성화 문서
S3도 선택한 AWS 리전에 오브젝트를 저장하고 CloudFront가 엣지 캐시를 담당합니다. S3를 CloudFront 원본으로 사용할 때는 버킷을 공개하기보다 Origin Access Control을 적용하는 편이 안전합니다. 사용자는 CloudFront로만 접근하고 CloudFront가 서명된 요청으로 비공개 S3 버킷을 읽게 됩니다. AWS CloudFront OAC 문서
사용자 → CDN 엣지 → 캐시 미스일 때만 원본 저장소이 한 줄이 비용과 응답 속도를 함께 설명해 줍니다.
원본의 강한 일관성은 CDN 캐시까지 보장하지 않습니다
S3와 R2는 모두 오브젝트 읽기와 쓰기에서 강한 일관성을 제공합니다.
S3는 모든 AWS 리전에서 PUT과 DELETE 이후 강한 읽기 일관성을 제공합니다. R2도 쓰기, 메타데이터 변경, 삭제와 목록 조회에 글로벌 강한 일관성을 제공합니다. AWS S3 일관성 문서, Cloudflare R2 일관성 문서
하지만 CDN 캐시는 별도 계층입니다. 원본의 logo.png를 바꿔도 엣지에는 이전 파일이 남을 수 있습니다. 원본에서 삭제한 파일도 TTL이 끝나거나 캐시를 비우기 전까지 제공될 수 있습니다.
저는 변경 가능한 정적 파일에 같은 URL을 계속 쓰기보다 파일명에 버전을 넣는 방식을 선호합니다.
/assets/logo.png
/assets/logo.a8107df.png두 번째 방식은 새 배포가 새 URL을 사용하기 때문에 전 세계 캐시를 급히 지울 일이 줄어듭니다. 같은 경로를 유지해야 한다면 CloudFront invalidation이나 Cloudflare cache purge를 배포 절차에 넣어야 합니다.
S3 호환은 S3와 동일하다는 뜻이 아닙니다
R2는 S3 호환 API를 제공합니다. 기본적인 PutObject, GetObject와 presigned URL을 사용하던 코드는 endpoint와 인증 설정을 바꾸는 것만으로 이전할 수 있는 경우가 많습니다.
다만 완전한 드롭인 대체재는 아닙니다. R2 공식 호환표에는 구현되지 않았거나 일부 기능만 지원하는 S3 API가 남아 있습니다. Bucket Policy, Replication, Intelligent-Tiering, Object Lock 같은 기능에 의존한다면 코드를 옮기기 전에 호환표부터 확인해야 합니다. R2 S3 API 호환표
저장과 다운로드만 사용하는 서비스는 R2로 이동하기 쉽습니다. IAM, KMS, 이벤트 알림, 수명 주기, 복제와 데이터 분석까지 AWS 안에서 연결했다면 S3의 비용에는 그 생태계를 유지하는 값도 포함돼 있습니다.
데이터 위치를 계약해야 한다면 차이가 분명합니다
S3는 버킷을 생성할 AWS 리전을 명시적으로 선택합니다. 선택한 리전의 오브젝트는 직접 복제하거나 전송하지 않는 한 해당 리전을 벗어나지 않습니다.
R2는 기본적으로 버킷 생성 요청과 가까운 위치를 자동 선택합니다. APAC 같은 Location Hint를 줄 수 있지만 best effort이며 특정 국가 배치를 보장하지는 않습니다. 현재 명시적인 관할 구역 제한은 EU와 FedRAMP 환경을 제공합니다. Cloudflare R2 데이터 위치 문서
한국 리전 저장처럼 물리적 위치를 계약이나 내부 정책으로 명확히 해야 한다면 S3가 설명하기 쉽습니다. 정확한 국가보다 글로벌 다운로드와 비용 단순성이 중요하다면 R2가 편합니다.
지금은 이렇게 선택합니다
이미 AWS에서 애플리케이션을 운영하고 Lambda, IAM, KMS, 이벤트 알림과 복제를 사용한다면 저는 S3에 CloudFront OAC를 붙입니다. 정액제 조건에 맞는 서비스라면 CloudFront 플랜도 함께 계산합니다.
이미지, 설치 파일, 공개 영상처럼 외부 다운로드가 많고 AWS 고유 기능 의존도가 낮다면 R2를 먼저 검토합니다. 이때 r2.dev를 운영 주소로 쓰지 않고 Custom Domain, Cache-Control, 캐시 규칙과 purge 절차까지 한 묶음으로 구성합니다.
선택 전에 확인할 숫자는 네 가지면 충분합니다.
- 평균 저장 용량
- 한 달 원본 읽기·쓰기 요청 수
- 사용자에게 전달되는 월간 데이터양
- 예상 CDN 캐시 적중률
이 숫자가 없으면 S3와 R2 중 어느 쪽이 저렴한지 답할 수 없습니다. 저장 가격표는 시작점일 뿐입니다. 실제 비용과 체감 속도는 그 앞에 놓인 글로벌 CDN 경로에서 결정됩니다.
함께 읽기
- 파일 저장소 비용 비교: Amazon S3와 Cloudflare R2, 무엇을 선택할까?웹 서비스에는 첨부 파일, 프로필 이미지, 업무 문서, 내보내기 파일과 백업 데이터를 저장할 공간이 필요하다. 대표적인 선택지는 Amazon S3와 Cloudflare R2다. 두 서비스 모두 안정적인 객체 스토리지지만 비용 구조와 강점은 꽤 다르다.
- 태그 485개를 전부 색인시키고 있었습니다: 블로그 SEO를 다시 손본 기록블로그에는 이미 canonical, sitemap, robots.txt, 글별 Open Graph 이미지, 구조화 데이터가 들어가 있었습니다. RSS와 Atom, JSON Feed도 있었고 관련 글 링크도 붙어 있었습니다. 그래서 처음에는 큰 구멍보다는 메타 설명을 조금 다듬는 정도를 예상했습니다.
- 한국에서 접속하는데 Cloudflare가 로스앤젤레스에서 응답했습니다이미지 엣지 캐시를 손보고 나서 얼마나 빨라졌는지 재고 있었습니다. 캐시에서 나오면 156ms, 오리진까지 가면 622ms. 4배 차이니까 좋아하고 있었는데, 156ms라는 숫자가 자꾸 걸렸습니다.
- Cache-Control: immutable인데 왜 Cloudflare는 계속 DYNAMIC이었을까요?CDN을 붙이고 응답 헤더에 긴 캐시 시간을 설정했는데도 CF-Cache-Status가 계속 DYNAMIC으로 표시되는 경우가 있습니다. 저희도 파일 제공 기능을 점검하면서 같은 상황을 만났습니다.
- Base64는 암호화가 아니다: 브라우저 Vault의 v2 봉투 암호화모바일 서명 파일이나 환경설정을 백업하다 보면 값 대부분이 Base64처럼 보일 때가 있다. 이때 가장 먼저 구분해야 할 사실이 있다.