[TIL] 서버 업로드 vs 클라이언트 직접 업로드(S3)

김재진·2026년 4월 17일

내일배움캠프

목록 보기
65/70

고민

상품 이미지를 S3에 저장할 때, 아래 두 가지 방식 중 어떤 것을 선택할지 고민했다.

  • 서버를 통해 S3에 업로드하는 방식
  • 클라이언트가 S3에 직접 업로드 (Presigned URL) 하는 방식

서버 업로드 방식의 문제

클라이언트 → (이미지 전송) → 서버 → (S3 업로드) → S3
  • 이미지 파일이 서버를 경유하므로 네트워크/메모리 부담 발생
  • 파일 크기가 클수록 요청 처리 시간이 길어져 다른 요청도 지연됨
  • 서버를 스케일 아웃해도 이미지 트래픽은 그대로 서버를 통과 → 근본적인 해결 불가

Presigned URL 방식을 선택한 이유

1. 클라이언트 → (Presigned URL 요청)   → 서버
2.             ← (Presigned URL 발급)   ←
3. 클라이언트 → (이미지 직접 업로드)    → S3
4. 클라이언트 → (imageUrl 포함 상품 등록 요청) → 서버

장점

  • 서버 부하 감소 — 이미지 업로드 트래픽이 서버를 거치지 않음
  • 전송 속도 향상 — S3가 업로드를 직접 수신하며, 이후 CloudFront CDN을 통해 빠른 배포 가능
  • 보안 — AWS 자격증명(Access Key)이 클라이언트에 노출되지 않음
  • URL 재사용 방지 — 만료 시간(presignedExpirationSeconds) 설정으로 유효기간 제한 가능

단점 및 대응

단점현재 대응
클라이언트에서 2번의 요청 필요 (URL 발급 + S3 업로드)UX 영향 미미, 허용 가능한 수준으로 판단
서버가 실제 S3 업로드 여부를 확인하기 어려움아래 내용 참고

업로드 검증 문제에 대한 고찰

클라이언트가 Presigned URL만 발급받고 실제로 업로드하지 않을 수 있다.

확장 시 해결 방법

  • S3 Event Notification + Lambda — 업로드 완료 이벤트를 트리거로 서버에 알림
  • HeadObject 검증 — 상품 등록 요청 시 서버가 해당 S3 key의 실제 존재 여부를 확인

현재 판단

imageUrl은 상품 등록 시에만 사용되므로, URL만 발급받고 업로드하지 않으면 해당 URL이 상품에 등록되지 않아 실질적인 문제가 발생하지 않는다. 현재 규모에서는 별도 검증 로직 없이도 충분하다고 판단하였다.

profile
개발공부 처음해보는 사람

0개의 댓글