대용량 파일은 왜 서버를 거치지 않고 R2나 S3로 올려야 할까?
브라우저가 파일을 애플리케이션 서버에 보내고, 서버가 다시 객체 저장소로 전달하는 방식은 이해하기 쉽다. 하지만 파일이 커지면 서버는 같은 데이터를 두 번 전송하고, 메모리와 실행 시간을 오래 점유한다. 서버리스 환경의 본문 크기 제한에도 걸리기 쉽다.
Vercel Functions는 요청과 응답 본문을 각각 4.5MB로 제한한다. 이보다 큰 파일을 함수가 중계하는 구조는 적합하지 않다. Vercel Functions 제한
서명된 URL을 이용한 직접 업로드
권장 흐름은 다음과 같다.
- 사용자가 파일 이름, 형식, 크기를 API에 알린다.
- API가 로그인, 업무 권한, 허용 형식과 용량을 확인한다.
- 서버가 짧게 유효한 업로드 URL과 서버가 정한 객체 키를 발급한다.
- 브라우저가 R2나 S3로 파일을 직접 전송한다.
- 업로드가 끝나면 애플리케이션에 완료를 알린다.
- 서버가 객체의 존재, 크기, 형식과 무결성을 다시 확인한다.
- 검사가 끝난 파일만 업무 데이터에 연결한다.
서명된 URL에는 저장소 비밀 키가 들어가지 않는다. 특정 객체와 작업, 만료 시간을 서명한 임시 권한이다. 다만 URL을 가진 사람은 만료 전까지 허용된 작업을 할 수 있으므로 짧게 발급하고 로그나 분석 도구에 남기지 않는다.
Cloudflare R2의 사전 서명 URL은 GET, HEAD, PUT, DELETE를 지원하고 만료 시간은 1초부터 7일까지 설정할 수 있다. Content-Type을 서명에 포함해 다른 형식의 업로드를 거부할 수도 있다. 브라우저에서 쓸 때는 허용한 출처만 접근하도록 CORS를 설정해야 한다. R2 사전 서명 URL
애플리케이션이 객체 키를 정해야 한다
사용자가 보낸 원본 파일명을 그대로 저장 경로로 쓰지 않는다. 조직 ID, 업무 ID, 무작위 ID를 조합한 키를 서버가 만들고, 원본 이름은 DB 메타데이터로 보존한다. 경로 충돌, 덮어쓰기, 다른 조직 파일 접근을 막기 쉽다.
권한도 읽기와 쓰기를 나눈다. 업로드 URL은 한 객체에 대한 PUT만 허용하고, 내려받기는 별도의 짧은 GET URL이나 인증 프록시를 사용한다. 공개 파일만 custom domain과 캐시를 사용한다.
업로드 완료를 그대로 신뢰하지 않는다
브라우저가 보낸 파일명과 MIME 형식은 조작할 수 있다. 서버나 후속 워커가 실제 크기, 파일 서명, 확장자, 악성 코드 여부를 확인한다. 검사 전 파일은 격리 경로에 두고, 통과한 뒤 공개 또는 업무 경로로 옮긴다.
DB에는 업로드 요청, 업로드됨, 검사 중, 사용 가능, 거부됨, 삭제됨 같은 상태를 둔다. 객체는 올라갔지만 완료 알림이 오지 않은 경우를 찾아 정리하는 작업도 필요하다.
큰 파일은 멀티파트로 나눈다
수백 MB 이상의 파일은 여러 조각으로 올리면 실패한 조각만 다시 보낼 수 있다. R2의 멀티파트 업로드는 마지막 조각을 제외하면 최소 5MiB, 조각당 최대 5GiB, 최대 10,000개 조각을 지원한다. 완료되지 않은 업로드는 기본 7일 뒤 중단되며 수명 주기로 기간을 바꿀 수 있다. R2 객체 업로드
R2와 S3 중 선택
| 기준 | R2 | S3 |
|---|---|---|
| 인터넷 전송 비용 | R2에서 나가는 전송료가 없음 | 리전과 전송 경로에 따라 과금 |
| 생태계 | S3 호환 API와 Cloudflare 연동 | AWS 서비스와 가장 폭넓게 연동 |
| 호환성 | 일부 S3 기능과 헤더는 미지원 | S3 기능의 기준 |
| 잘 맞는 경우 | 다운로드가 많고 Cloudflare를 쓰는 서비스 | AWS 내부 처리, 규정, 고급 저장 기능 연동 |
R2는 S3 API와 폭넓게 호환되지만 ACL, KMS 헤더, 일부 Object Lock 관련 기능처럼 지원하지 않는 항목이 있다. 기존 S3 도구를 그대로 옮기기 전에 실제 사용하는 API를 확인한다. R2 S3 API 호환성
직접 업로드의 목적은 서버 비용만 줄이는 것이 아니다. 큰 파일 전송을 객체 저장소에 맡기고, 애플리케이션은 권한, 상태, 검사와 업무 연결에 집중하게 만드는 것이다.
함께 읽기
- 20명에서 100명까지, 사내 시스템 배포 아키텍처 설계하기사내 시스템은 직원 수가 적다고 해서 항상 가볍지 않다. 20명이 쓰는 문서 변환 시스템은 100명이 쓰는 단순 결재 시스템보다 더 많은 CPU와 저장 공간을 요구할 수 있다. 그래서 배포 구조는 인원수보다 동시 접속, 요청 시간, 파일 크기, 실시간 연결 수, 장애 허용 시간을 기준으로 정해야 한다.
- 파일 저장소 비용 비교: Amazon S3와 Cloudflare R2, 무엇을 선택할까?웹 서비스에는 첨부 파일, 프로필 이미지, 업무 문서, 내보내기 파일과 백업 데이터를 저장할 공간이 필요하다. 대표적인 선택지는 Amazon S3와 Cloudflare R2다. 두 서비스 모두 안정적인 객체 스토리지지만 비용 구조와 강점은 꽤 다르다.
- 사내 시스템 공개 전 확인해야 할 운영 체크리스트 30가지사내 시스템은 외부 고객 서비스보다 사용자가 적다는 이유로 공개 전 점검이 짧아지기 쉽다. 하지만 결재, 계약, 인사, 회계처럼 업무의 기준이 되는 시스템은 한 번의 권한 오류나 데이터 손실도 실제 업무 중단으로 이어진다.
- 듀오랩스가 사내 시스템을 설계하고 운영하는 7가지 원칙사내 시스템의 좋은 아키텍처는 가장 큰 서버나 가장 복잡한 기술 조합이 아니다. 현재 업무를 무리 없이 지원하고, 문제가 생겼을 때 되돌릴 수 있으며, 사용자가 늘면 필요한 부분만 확장할 수 있는 구조다.
- 월 10달러 VPS가 정말 더 저렴할까? 숨은 운영 비용 계산하기월 10달러 안팎의 VPS를 보면 Vercel, Supabase 같은 관리형 서비스를 합친 것보다 훨씬 저렴해 보인다. 실제로 안정적인 부하가 있고 서버를 운영할 사람이 있다면 VPS가 경제적일 수 있다. 하지만 인스턴스 가격만 비교하면 백업, 저장 공간, 전송량, 보안 패치, 장애 대응 시간이 빠진다.