KoderKoder.ai
가격엔터프라이즈교육투자자용
로그인시작하기

제품

가격엔터프라이즈투자자용

리소스

문의하기지원교육블로그

법적 고지

개인정보 처리방침이용 약관보안허용 사용 정책악용 신고

소셜

LinkedInTwitter
Koder.ai
언어

© 2026 Koder.ai. All rights reserved.

홈›블로그›ZSTD vs Brotli vs GZIP: API 압축 선택하기
2025년 9월 23일·6분

ZSTD vs Brotli vs GZIP: API 압축 선택하기

API용 ZSTD, Brotli, GZIP 비교: 속도, 압축률, CPU 비용과 프로덕션에서 JSON 및 바이너리 페이로드에 대한 실무적 기본값.

ZSTD vs Brotli vs GZIP: API 압축 선택하기

API 압축이란(그리고 언제 가치가 있는가)

API 응답 압축은 서버가 응답 바디(대개 JSON)를 네트워크로 보내기 전에 더 작은 바이트 스트림으로 인코딩하는 것을 말합니다. 클라이언트(브라우저, 모바일 앱, SDK 또는 다른 서비스)는 이를 해제한 뒤 처리합니다. HTTP에서는 Accept-Encoding(클라이언트가 지원하는 것)과 Content-Encoding(서버가 선택한 것) 같은 헤더로 협상합니다.

API에서 압축이 하는 일

압축은 주로 세 가지를 제공합니다:

  • 대역폭 감소: 작은 응답은 엔드투엔드에서 적은 바이트를 소비합니다.
  • 제약된 링크에서의 낮은 지연: 바이트가 적으면 모바일, 혼잡한 Wi‑Fi, 리전 간 호출에서 다운로드가 빠를 수 있습니다.
  • 발신 비용 감소: 아웃바운드 데이터에 비용을 지불한다면 전송 크기를 줄이면 직접적으로 비용을 낮출 수 있습니다.

대가는 명확합니다: 압축은 대역폭을 절약하지만 CPU(압축/해제)와 때로는 메모리(버퍼)에 비용을 부과합니다. 그게 가치 있는지는 병목이 무엇인지에 달려 있습니다.

압축이 가장 효과적인 경우

압축은 다음과 같은 응답에서 빛을 발합니다:

  • 텍스트 중심이고 반복적인 데이터(예: JSON, GraphQL 응답, HTML, 로그)
  • 중간~대형 크기, 수십~수백 KB를 줄이는 것이 의미가 있을 때
  • 느리거나 비용이 높은 네트워크(모바일, 국제 고객, 리전 간 트래픽)

대형 JSON 목록(카탈로그, 검색 결과, 분석 등)을 반환한다면 압축은 가장 쉬운 이득 중 하나입니다.

압축이 거의 도움이 되지 않는 경우

압축은 다음과 같은 경우 CPU 낭비가 될 수 있습니다:

  • 작은 응답(예: 수백 바이트). 헤더와 CPU 오버헤드가 절감 효과를 상쇄할 수 있습니다.
  • 이미 압축된 데이터(JPEG/PNG, MP4, ZIP, 많은 PDF). 재압축으로 거의 줄어들지 않거나 오히려 커질 수 있습니다.
  • CPU 바운드 서비스(연산이 많은 핫 엔드포인트). 압축을 추가하면 테일 레이턴시가 증가할 수 있습니다.

이 가이드 전체에서 사용할 결정 축

ZSTD vs Brotli vs GZIP 중 선택할 때 실무적 결정은 보통 다음으로 귀결됩니다:

  1. 크기 절감(압축률)
  2. 지연(서버의 TTFB + 클라이언트 디코드 시간)
  3. 클라이언트 지원(호출자와 중간자들이 신뢰성 있게 처리하는지)

이 글의 나머지는 특정 API와 트래픽 패턴에 대해 이 세 가지를 균형 있게 맞추는 방법입니다.

ZSTD vs Brotli vs GZIP: 빠른 비교

세 코덱 모두 페이로드 크기를 줄이지만, 속도·압축률·호환성 등 서로 다른 제약을 최적화합니다.

한눈 요약

  • ZSTD (Zstandard): 지연에 민감하고 CPU가 예측 가능해야 할 때 낮은 지연과 예측 가능한 CPU 사이에서 가장 균형이 좋습니다. 좋은 압축률에 느리지 않습니다.
  • Brotli: 텍스트 중심 응답(JSON, HTML 등)에서 가장 작은 전송 바이트를 자주 기록합니다. 높은 설정은 더 많은 CPU를 요구할 수 있습니다.
  • GZIP: “어디서나 동작”하는 옵션. 폭넓게 지원되며 운영화하기 쉽지만, 동일한 CPU 예산에서 보통 느리거나 더 큰 결과를 냅니다.

전형적 강점(그리고 API에 의미하는 바)

ZSTD의 속도: 엔드포인트가 테일 레이턴시에 민감하거나 서버가 CPU 바운드인 경우에 좋습니다. 중간~대형 JSON 응답에서는 네트워크 시간에 비해 압축 오버헤드가 보통 무시될 만큼 빠릅니다.

Brotli의 압축률: 대역폭이 주요 제약(모바일 클라이언트, 비싼 egress, CDN 중심)이고 응답이 주로 텍스트일 때 유리합니다. 작은 응답에서도 CPU를 더 들여서 작게 만드는 것이 가치가 있을 수 있습니다.

GZIP의 호환성: 최대한 많은 클라이언트를 지원해야 하고 협상 실패 위험을 최소화해야 할 때 좋습니다(오래된 SDK, 임베디드 클라이언트, 레거시 프록시). 최상의 성능은 아니더라도 안전한 기준입니다.

“압축 레벨”이 실제로 바꾸는 것

압축 “레벨”은 CPU 시간과 출력 파일 크기 사이의 절충을 설정하는 프리셋입니다:

  • 낮은 레벨: 더 빠른 압축, 더 큰 페이로드. 실시간 API에 적합합니다.
  • 높은 레벨: 더 작은 페이로드, 느린 압축(때로는 더 많은 메모리). 캐시 가능한 큰 응답에 적합합니다.

세 포맷 모두에서 디코딩은 보통 압축보다 훨씬 저렴하지만, 매우 높은 레벨은 클라이언트 CPU/배터리에도 부담이 될 수 있습니다(특히 모바일).

간단한 경험칙

  • 기본 선택: 지연이 중요하면 대부분의 JSON/REST/GraphQL API에 ZSTD를 사용하세요.
  • Brotli로 전환: 최소 바이트가 목표이고(텍스트 중심 응답, CDN 전달, 느린 네트워크) 추가 CPU를 감당할 수 있을 때.
  • GZIP 유지: 호환성이 가장 중요하거나 인프라/도구가 최신 인코딩을 지원하지 않을 때.

압축률 vs 지연: 핵심 트레이드오프

압축은 종종 “작아진 응답 = 더 빠른 API”로 팔립니다. 느리거나 비용이 높은 네트워크에서는 자주 맞지만 자동은 아닙니다. 압축이 서버 CPU 시간을 충분히 추가하면, 전송 바이트가 적어도 요청이 더 느려질 수 있습니다.

시간이 어디로 가는가

두 가지 비용을 구분하면 도움이 됩니다:

  • 압축 시간(서버 측): 서버가 바이트를 보내기 전에 수행하는 작업. 응답 시간(TTFB)에 직접 추가될 수 있습니다.
  • 디코딩 시간(클라이언트 측): 바이트를 받은 뒤 수행하는 작업. 보통 압축보다 저렴하지만 저전력 장치나 고처리량 클라이언트에서는 영향이 있습니다.

높은 압축률은 전송 시간을 줄이지만, 압축으로 인해 응답당 15–30ms가 늘어난다면 특히 빠른 연결에서는 오히려 느려질 수 있습니다.

부하 시 테일 레이턴시 함정

부하가 걸리면 압축은 평균보다 p95/p99 레이턴시를 더 악화시킬 수 있습니다. CPU 사용량이 피크를 치면 요청이 큐에 쌓이고, 큐잉은 작은 비용을 큰 지연으로 증폭합니다—평균 레이턴시는 괜찮아 보여도 느린 사용자들이 고통받습니다.

성능 기능처럼 측정하라

추측하지 마세요. A/B 테스트나 단계적 롤아웃으로 다음을 비교하세요:

  • p50 및 p95 레이턴시(이상적으로 p99도)
  • API 인스턴스의 CPU 사용률 및 포화 상태
  • 응답 크기 및 TTFB

실제 트래픽 패턴과 페이로드로 테스트하세요. “최고” 압축 레벨은 바이트가 가장 많이 줄어드는 것이 아니라 전체 시간을 줄이는 수준입니다.

서버 및 클라이언트의 CPU와 메모리 비용

압축은 무료가 아닙니다—작업을 네트워크에서 CPU와 메모리로 옮깁니다. API에서는 요청 처리 시간 증가, 메모리 풋프린트 상승, 때로는 클라이언트 측 지연으로 드러납니다.

CPU는 어디에 쓰이나

대부분의 CPU는 응답 압축에 사용됩니다. 압축은 패턴을 찾고 상태/사전을 구성하며 인코딩된 출력을 작성합니다.

디코딩은 보통 더 저렴하지만 여전히 관련됩니다:

  • 서버는 때때로 요청을 해제압축(decompress)할 수 있습니다(JSON API에서는 드묾, 업로드나 배치 이벤트에서는 흔함).
  • 클라이언트는 응답을 디코딩한 뒤 JSON을 파싱합니다.

API가 이미 CPU 바운드라면(무거운 인증, 비싼 쿼리 등), 높은 압축 레벨을 켜면 페일리어 테일 레이턴시가 증가할 수 있습니다.

메모리 고려사항

압축은 몇 가지 방식으로 메모리를 늘립니다:

  • 버퍼: 구현체는 입력/출력 버퍼가 필요할 수 있으며, 큰 페이로드는 더 큰 버퍼를 의미합니다.
  • 전체 버퍼링 vs 스트리밍: 스트리밍 압축은 전송을 더 빨리 시작하고 메모리 사용을 낮게 유지할 수 있지만, 전체 버퍼링은 요청당 피크 메모리를 증가시킵니다.

컨테이너 환경에서는 높은 피크 메모리가 OOM 킬이나 더 낮은 인스턴스 밀도로 이어질 수 있습니다.

오토스케일링과 컨테이너 한계에 미치는 영향

압축은 응답당 CPU 사이클을 늘려 인스턴스당 처리량을 줄입니다. 이는 오토스케일링을 더 자주 트리거해 비용을 올릴 수 있습니다. 흔한 패턴은: 대역폭 비용은 줄지만 CPU 사용은 늘어납니다—어떤 자원이 더 희소한지에 따라 옳은 선택이 달라집니다.

클라이언트에서 디코딩 속도가 중요한 이유

모바일이나 저전력 장치에서는 디코딩이 렌더링, JS 실행, 배터리 사용과 경쟁합니다. 몇 KB를 절약하지만 디코딩에 시간이 더 오래 걸리면 특히 “사용 가능한 데이터까지의 시간”에서 느리게 느껴질 수 있습니다.

API용 ZSTD: 강점, 한계, 권장 기본값

팀과 함께 빌드
팀을 하나의 워크스페이스로 모아 함께 빌드, 배포, 성능 변경을 검토하세요.
팀 초대

Zstandard(ZSTD)는 느리지 않으면서 강한 압축률을 제공하도록 설계된 현대적인 포맷입니다. 많은 JSON 중심 API에서 좋은 "기본값"입니다: GZIP보다 눈에 띄게 작은 응답을 비슷하거나 더 낮은 지연으로 제공하고, 클라이언트 측 디코딩도 매우 빠릅니다.

ZSTD가 잘하는 것

ZSTD는 단순히 바이트가 작아지는 것이 아니라 엔드투엔드 시간을 신경쓸 때 특히 가치가 있습니다. 비교적 빠른 압축과 매우 빠른 디코딩을 제공해 요청 처리의 밀접한 경쟁이 있을 때 유리합니다.

소형~중형 JSON은 의미 있는 이득을 볼 수 있고, 대형 응답은 더 큰 이득을 얻습니다.

API에 대한 합리적 압축 레벨

대부분의 API에는 낮은 레벨(보통 1–3)로 시작하세요. 이는 지연/크기 절충에서 가장 좋은 경우가 많습니다.

다음 경우에만 높은 레벨을 사용하세요:

  • 페이로드가 크다(수백 KB ~ MB)
  • 대역폭이 비싸거나 제약이 있다
  • CPU가 병목이 아님이 측정으로 확인되었다

실용적 접근법은 전역적으로 낮은 기본값을 두고, 일부 대형 응답 엔드포인트에 대해서만 레벨을 높이는 것입니다.

스트리밍과 사전(dictionary) 모드

ZSTD는 스트리밍을 지원해 큰 응답에서 피크 메모리를 줄이고 더 빨리 전송을 시작할 수 있습니다.

사전 모드는 많은 유사한 객체(반복 키, 안정적 스키마)를 반환하는 API에서 큰 이득이 될 수 있습니다. 사전은 작은 빈번한 페이로드에 특히 효과적이며 버전 관리 가능한 사전을 안전하게 관리할 수 있을 때 유용합니다.

호환성 한계

서버 측 지원은 많은 스택에서 간단하지만 클라이언트 호환성이 결정 요인이 될 수 있습니다. 일부 HTTP 클라이언트, 프록시, 게이트웨이는 기본적으로 Content-Encoding: zstd를 광고하거나 수용하지 않을 수 있습니다.

서드파티 소비자가 있다면 폴백(보통 GZIP)을 유지하고 Accept-Encoding에 명확히 포함된 경우에만 ZSTD를 활성화하세요.

API용 Brotli: 언제 유리하고 언제 아닌가

Brotli는 텍스트를 매우 잘 압축하도록 설계되었습니다. JSON, HTML 같은 “단어 많은” 페이로드에서 GZIP보다 압축률이 좋을 때가 많습니다—특히 높은 레벨에서.

Brotli가 이기는 경우

텍스트 중심 응답이 Brotli의 강점입니다. 대형 JSON 문서(카탈로그, 검색 결과, 구성 블롭 등)는 Brotli로 상당히 줄일 수 있어 느린 네트워크에서 이득이 크고 발신 비용을 줄이는 데 도움이 됩니다.

또한 한 번 압축해서 여러 번 제공하는 경우(캐시 가능한 응답, 버전된 리소스)에는 높은 레벨의 Brotli가 CPU 비용을 요청 수로 나누어 충분히 가치가 됩니다.

Brotli가 기대에 못 미치는 경우

동적 생성 응답(요청마다 생성)에서는 Brotli의 최상의 비율이 높은 레벨을 요구하는데 이는 CPU 비용이 크고 레이턴시를 늘립니다. 압축 시간을 고려하면 ZSTD(또는 잘 튜닝된 GZIP)에 비해 실무상의 이점이 예상보다 작을 수 있습니다.

또한 잘 압축되지 않는 페이로드(이미 압축된 데이터, 많은 바이너리 형식)에는 매력적이지 않습니다—그저 CPU만 소모하게 됩니다.

실무적 레벨 가이드

  • 런타임 압축: CPU 스파이크를 피하기 위해 낮은 레벨(보통 1–4)을 사용하세요.
  • 사전압축/정적: 요청당 비용을 분산시킬 수 있다면 높은 레벨(보통 8–11)을 고려하세요.

클라이언트 지원 참고

브라우저는 HTTPS에서 Brotli를 대체로 잘 지원하므로 웹 트래픽에 인기입니다. 비브라우저 API 클라이언트(모바일 SDK, IoT 장치, 오래된 HTTP 스택)는 지원이 일관되지 않을 수 있으니 Accept-Encoding으로 올바르게 협상하고 폴백(보통 GZIP)을 유지하세요.

API용 GZIP: 호환성과 실무 성능

GZIP은 여전히 API 압축의 기본 답변입니다. 거의 모든 HTTP 클라이언트, 브라우저, 프록시, 게이트웨이가 Content-Encoding: gzip을 이해하고, 그 예측 가능성이 제어 불가능한 경로들 사이에서 중요합니다.

여전히 흔한 이유

GZIP의 장점은 “최고”라서가 아니라 거의 잘못된 선택이 아니기 때문입니다. 많은 조직이 운영 경험을 가지고 있고, 웹 서버에 합리적 기본값이 있으며, 중간자가 최신 인코딩을 잘못 처리하는 경우가 GZIP에서는 적습니다.

API용 실무 압축 레벨

API 페이로드(주로 JSON)에 대해서는 중간~낮은 레벨이 절충점입니다. 레벨 1–6은 대부분의 크기 감소를 제공하면서 CPU를 합리적으로 유지합니다.

아주 높은 레벨(8–9)은 약간 더 줄일 수 있지만 동적 응답과 지연이 중요한 트래픽에는 보통 가치가 적습니다.

최신 CPU에서의 비교

현대 하드웨어에서 GZIP은 비슷한 압축률에서 일반적으로 ZSTD보다 느리고, 텍스트에서 Brotli의 최고 비율을 따라잡지 못합니다. 실무 API 워크로드에서는:

  • ZSTD가 바이트당 속도에서 이기는 경우가 많습니다.
  • Brotli는 고도로 압축 가능한 텍스트에서 크기로 이길 수 있지만 설정에 따라 CPU가 더 많이 듭니다.
  • GZIP은 널리 최적화되어 있어 경쟁력이 유지됩니다.

호환성 엣지 케이스

오래된 클라이언트, 임베디드 디바이스, 엄격한 기업 프록시, 레거시 게이트웨이 등을 지원해야 한다면 GZIP이 가장 안전한 선택입니다. 일부 중간자는 알 수 없는 인코딩을 제거하거나 패스스루하지 못하거나 협상을 깨뜨릴 수 있습니다—GZIP에서는 이런 문제가 덜 발생합니다.

환경이 혼재되어 불확실하면 GZIP으로 시작하고 완전 제어 경로에 대해서만 ZSTD/Brotli를 추가하는 것이 안전한 롤아웃 전략입니다.

페이로드 유형: 무엇이 잘 압축되고 무엇이 아닌가

항상 롤백 준비
스냅샷과 롤백을 사용해 스트레스 있는 사고 없이 압축 변경을 되돌리세요.
롤백

압축 성공은 알고리즘만의 문제가 아닙니다. 가장 큰 결정자는 전송하는 데이터의 유형입니다. 어떤 페이로드는 ZSTD/Brotli/GZIP으로 크게 줄고, 어떤 것은 거의 줄지 않아 단지 CPU만 소모합니다.

높은 보상(잘 압축되는 후보)

텍스트 중심 응답은 반복 키, 공백, 예측 가능한 패턴 때문에 매우 잘 압축됩니다:

  • JSON(일반 REST 응답 포함)
  • GraphQL 응답(필드명이 반복되는 경우가 흔함)
  • XML 및 HTML
  • 큰 플레인 텍스트 로그와 API가 반환하는 에러 트레이스

반복성과 구조가 많을수록 압축률이 좋습니다.

바이너리 페이로드: “측정이 필요”

Protocol Buffers나 MessagePack 같은 바이너리 형식은 JSON보다 컴팩트하지만 무작위는 아닙니다. 반복 태그, 유사한 레코드 레이아웃, 예측 가능한 시퀀스를 포함할 수 있어 여전히 압축될 수 있는 경우가 많습니다, 특히 큰 응답이나 리스트가 많은 엔드포인트에서는 더더욱. 신뢰할 수 있는 답은 실측입니다: 실제 트래픽 샘플로 압축 온/오프를 비교하세요.

보통 압축 가치가 없는 것(이미 압축됨)

많은 형식은 내부적으로 이미 압축을 사용합니다. HTTP 응답 수준에서 추가 압축을 적용하면 거의 절감이 없고 오히려 응답 시간이 증가할 수 있습니다:

  • 이미지: JPEG, PNG, WebP
  • 비디오/오디오: MP4 등
  • 아카이브: ZIP, gzip 파일
  • PDF: 종종 내부적으로 압축을 사용

이 경우 콘텐츠 타입으로 압축을 비활성화하는 것이 일반적입니다.

실용적 휴리스틱(단순하게 유지)

간단한 접근은 응답이 최소 크기를 넘을 때만 압축하는 것입니다:

  • 최소 응답 크기 임계값을 설정(예: 몇 KB)하여 Content-Encoding을 활성화
  • 큰 텍스트 응답은 항상 압축; 헤더가 지배적인 작은 JSON은 건너뛸 것

이렇게 하면 CPU가 실제로 대역폭을 줄이고 엔드투엔드 성능을 개선하는 페이로드에 집중됩니다.

HTTP 헤더와 협상: 올바르게 구성하기

클라이언트와 서버가 인코딩에 합의해야 압축이 원활히 동작합니다. 이 합의는 클라이언트가 보내는 Accept-Encoding과 서버가 보내는 Content-Encoding으로 이뤄집니다.

Accept-Encoding과 Content-Encoding(간단한 예)

클라이언트는 디코딩 가능한 것을 광고합니다:

GET /v1/orders HTTP/1.1
Host: api.example
Accept-Encoding: zstd, br, gzip

서버는 하나를 선택하고 사용한 것을 선언합니다:

HTTP/1.1 200 OK
Content-Type: application/json
Content-Encoding: zstd

클라이언트가 Accept-Encoding: gzip만 보냈는데 서버가 Content-Encoding: br로 응답하면 해당 클라이언트는 본문을 파싱하지 못할 수 있습니다. 클라이언트가 Accept-Encoding을 보내지 않으면 가장 안전한 기본은 압축하지 않는 것입니다.

서버 측 우선순위 선택

API에서는 실무적으로 다음과 같은 우선순위를 사용하는 경우가 많습니다:

  • 먼저 zstd(속도/비율 균형이 좋음)
  • 그다음 br(종종 더 작음, 가끔 느림)
  • 그다음 gzip(최대한의 호환성)

즉: zstd > br > gzip.

이 규칙이 항상 보편적인 것은 아닙니다: 트래픽이 대부분 브라우저라면 br의 우선순위를 더 올려야 하고, 오래된 모바일 클라이언트가 많다면 gzip이 가장 안전한 선택일 수 있습니다.

Vary: Accept-Encoding과 캐싱

응답을 여러 인코딩으로 제공할 수 있다면 다음을 추가하세요:

Vary: Accept-Encoding

이 헤더가 없으면 CDN이나 프록시가 gzip(또는 zstd) 버전을 캐시하고 해당 인코딩을 요청하지 않은 클라이언트에게 잘못 제공할 수 있습니다.

엣지 케이스와 안전한 폴백

일부 클라이언트는 지원을 광고하지만 디코더에 버그가 있을 수 있습니다. 탄력성을 유지하려면:

  • zstd에 대한 디코딩 오류가 급증하면 임시로 gzip으로 폴백
  • 문제를 일으키는 사용자 에이전트나 SDK 버전에 대해 허용 목록(allowlist)을 사용
  • 인증, 웹훅 같은 중요한 엔드포인트는 압축을 비활성화하거나 가장 호환성 높은 옵션만 사용

협상은 모든 바이트를 쥐어짜는 것보다 클라이언트를 깨뜨리지 않는 데 더 중점을 둬야 합니다.

HTTP/2, HTTP/3, CDN, 게이트웨이

빠르게 배포하고 측정
호스팅으로 백엔드를 배포하고 압축이 프로덕션의 p95 지연 시간에 미치는 영향을 확인하세요.
지금 배포

API 압축은 고립된 문제가 아닙니다. 전송 프로토콜, TLS 오버헤드, CDN/게이트웨이가 실제 결과를 바꾸거나 잘못 구성되면 문제를 일으킬 수 있습니다.

HTTP/2와 HTTP/3: 멀티플렉싱, HOL, 압축의 변화

HTTP/2에서는 여러 요청이 하나의 TCP 연결을 공유합니다. 연결 오버헤드는 줄지만, 패킷 손실은 TCP 수준에서 모든 스트림을 차단할 수 있습니다. 압축은 응답 본문을 줄여 손실 사건 뒤에 “갇히는” 데이터 양을 줄여 도움을 줍니다.

HTTP/3는 QUIC(UDP) 위에서 동작해 스트림 간 TCP 수준의 헤드오브라인 블로킹을 피합니다. 페이로드 크기는 여전히 중요하지만 손실에 따른 패널티는 연결당 덜 극단적입니다. 실무에서는 압축이 여전히 유용하며, 주로 대역폭 절감과 더 빠른 "time to last byte" 측면에서 혜택이 나타납니다.

TLS 상호작용: CPU 예산을 무시하지 마라

TLS는 이미 CPU를 소모합니다(핸드셰이크, 암호화/복호화). 높은 레벨의 압축을 추가하면 피크 시 CPU 한도를 넘길 수 있습니다. 따라서 프로덕션에서는 "빠른 압축과 적당한 비율" 설정이 보통 "최대 비율"보다 더 낫습니다.

CDN과 API 게이트웨이: 자동 압축, 패스스루, 또는 제거

일부 CDN/게이트웨이는 특정 MIME 타입을 자동으로 압축하고, 일부는 오리진이 보낸 것을 그대로 통과시키며, 몇몇은 잘못 구성되면 Content-Encoding을 제거하거나 정규화할 수 있습니다.

라우트별 동작을 검증하고 Vary: Accept-Encoding이 유지되도록 하여 캐시가 잘못된 버전을 제공하지 않도록 하세요.

캐싱 전략: 엣지 vs 오리진(여러 변형)

엣지에서 캐시한다면 인코딩별 별도 변형(gzip/br/zstd)을 저장하는 것을 고려하세요. 매 요청마다 다시 압축하는 대신 미리 압축된 버전을 캐시하는 것이 비용 효율적입니다. 오리진에서 캐시하는 경우에도 엣지가 협상하고 여러 인코딩을 캐시하도록 할 수 있습니다.

핵심은 일관성입니다: 올바른 Content-Encoding, 올바른 Vary, 그리고 어디서 압축을 담당할지의 명확한 소유구조.

권장 기본값 및 튜닝 플레이북

시나리오별 제안 기본값

  • 브라우저 대상 API: 클라이언트가 Accept-Encoding: br을 광고하면 Brotli를 우선시하세요. 브라우저는 Brotli 디코딩을 효율적으로 수행하고 텍스트 응답에서 보통 더 나은 크기 절감을 제공합니다.
  • 내부 서비스 대 서비스 API: 양쪽을 제어할 수 있다면 ZSTD를 기본으로 쓰세요. 보통 GZIP보다 유사하거나 더 나은 비율을 더 빠르게 제공합니다.
  • 다양한 SDK가 사용하는 공개 API: 보편적 기준으로 GZIP을 유지하고, 명시적으로 지원하는 클라이언트에 대해 ZSTD를 옵트인으로 제공하세요. 오래된 HTTP 스택을 깨뜨리지 않도록 합니다.

보수적 시작 레벨

초기에는 놀라움을 줄 가능성이 적은 레벨로 시작하세요:

  • Brotli: 동적 API 응답에는 레벨 4–6(높은 레벨은 서버 CPU를 눈에 띄게 올릴 수 있음)
  • ZSTD: 일반 API 페이로드에는 레벨 3–5
  • GZIP: 좋은 기본값으로 레벨 5–6

더 강한 비율이 필요하면 프로덕션 유사 페이로드 샘플로 검증하고 p95/p99 레이턴시를 추적한 뒤 레벨을 올리세요.

최소 크기 임계값(및 튜닝)

작은 응답을 압축하면 CPU 비용이 절감보다 클 수 있습니다. 실무 시작점:

  • 대부분의 API에서 1–2 KB 미만은 압축하지 않기
  • CPU가 부족하거나 대화형(챗티) 트래픽일 경우 4 KB 고려

(1) 절감된 바이트, (2) 추가된 서버 시간, (3) 엔드투엔드 레이턴시 변화 를 비교하며 튜닝하세요.

제어 노출의 안전한 방법

압축은 기능 플래그 뒤에 숨겨서 롤아웃한 뒤, 엔드포인트별 구성(예: /v1/search는 활성화, 이미 작은 엔드포인트는 비활성화)을 추가하세요. 문제 해결과 엣지 클라이언트를 위해 Accept-Encoding: identity로 클라이언트 옵트아웃을 제공하세요. 캐시 정확성을 위해 항상 Vary: Accept-Encoding을 포함하세요.

현대적 빌드 및 배포 워크플로에서의 위치

빠르게 API를 생성하는 환경(예: React 프런트엔드와 Go + PostgreSQL 백엔드를 빠르게 배포)에서는 압축이 "작은 설정, 큰 영향"을 주는 구성 요소 중 하나입니다. 프로덕션에서 엔드포인트와 페이로드 모양이 안정화되면 응답 압축과 캐시 헤더를 튜닝하는 것이 흔한 과정입니다.

Koder.ai 같은 플랫폼에서는 팀이 전체 스택을 빠르게 프로토타입하고 배포한 뒤, 프로덕션 트래픽을 기반으로 압축 동작을 튜닝하는 경우가 많습니다. 핵심 요점은 같습니

자주 묻는 질문

언제 API 응답 압축을 활성화하는 것이 실제로 가치가 있나요?

응답이 텍스트 중심(JSON/GraphQL/XML/HTML)이고 중간 크기 이상이며 사용자가 느리거나 비용이 높은 네트워크에 있거나 발신(egress) 비용이 유의미할 때 응답 압축을 사용하세요. 작은 응답, 이미 압축된 미디어(JPEG/MP4/ZIP/PDF) 또는 추가 작업이 p95/p99 레이턴시를 악화시키는 CPU 바운드 서비스에는 압축을 건너뛰거나 높은 임계값을 사용하세요.

응답이 더 작아졌는데도 압축 때문에 API가 느려질 수 있는 이유는 무엇인가요?

압축은 대역폭을 CPU(및 때로는 메모리)로 교환하기 때문에 API가 더 느려질 수 있습니다. 압축에 드는 시간은 서버가 바이트 전송을 시작하는 시점을 지연시키고, 부하가 걸리면 큐잉이 증폭되어 특히 **테일 레이턴시(p95/p99)**를 악화시킬 수 있습니다. 가장 좋은 설정은 단순히 바이트를 줄이는 것이 아니라 엔드투엔드 소요 시간을 줄이는 설정입니다.

ZSTD, Brotli, GZIP 중 어떻게 선택해야 하나요?

많은 API에서 실용적인 우선순위는 다음과 같습니다:

  • zstd 우선(빠르고 좋은 비율)
  • 그다음 br(텍스트에서 더 작을 수 있으나 CPU 비용이 클 수 있음)
  • 그다음 gzip(가장 넓은 호환성)

항상 최종 선택은 클라이언트가 에 광고한 내용을 기준으로 하고, 안전한 폴백(보통 또는 )을 유지하세요.

동적 API 응답에 대해 어떤 압축 레벨이 합리적인 기본값인가요?

낮은 수준에서 시작하고 측정하세요.

  • ZSTD: 대부분의 동적 JSON API에 대해 레벨 1–3(또는 경우에 따라 3–5) 권장
  • Brotli: 런타임 압축에는 레벨 권장; 사전압축/정적에는 고려
모든 응답을 압축해야 하나요, 아니면 특정 크기 이상만 압축해야 하나요?

작은 페이로드에 대해 CPU를 낭비하지 않도록 최소 응답 크기 임계값을 사용하세요.

  • 일반 시작점: 1–2 KB
  • CPU가 부족하거나 요청이 매우 잦다면: 4 KB 고려

엔드포인트별로 바이트 절감, 추가된 서버 시간, p50/p95/p99에 미치는 영향을 비교하며 튜닝하세요.

어떤 페이로드 유형이 잘 압축되고, 어떤 것은 보통 그렇지 않나요?

구조화되고 반복적인 콘텐츠에 압축 효과가 큽니다:

API에서 Accept-Encoding과 Content-Encoding은 어떻게 작동하나요?

HTTP 협상에 따라야 합니다:

  • 클라이언트가 Accept-Encoding을 보냅니다(예: zstd, br, gzip).
  • 서버는 지원되는 인코딩 중 하나로 응답합니다(예: Content-Encoding: zstd).

클라이언트가 을 보내지 않았다면 안전한 기본은 보통 입니다. 클라이언트가 광고하지 않은 을 반환하면 클라이언트가 본문을 파싱하지 못할 위험이 있습니다.

압축을 사용할 때 왜 Vary: Accept-Encoding이 중요한가요?

다음 헤더를 추가하세요:

  • Vary: Accept-Encoding

이 헤더는 CDN/프록시가 (예:) gzip 응답을 캐시해 해당 인코딩을 요청하지 않거나 디코딩하지 못하는 클라이언트에게 잘못 제공하는 것을 방지합니다. 여러 인코딩을 지원하면 이 헤더는 정확한 캐싱 동작에 필수입니다.

프로덕션에서 가장 흔한 압축 버그는 무엇인가요?

대표적인 장애 원인은 다음과 같습니다:

API 압축을 안전하게 롤아웃하고 모니터링하려면 어떻게 해야 하나요?

성능 기능처럼 롤아웃하세요:

  • 카나리(소수 트래픽)로 시작해 점진적으로 증대(예: 1% → 5% → 25% → 100%)
목차
API 압축이란(그리고 언제 가치가 있는가)ZSTD vs Brotli vs GZIP: 빠른 비교압축률 vs 지연: 핵심 트레이드오프서버 및 클라이언트의 CPU와 메모리 비용API용 ZSTD: 강점, 한계, 권장 기본값API용 Brotli: 언제 유리하고 언제 아닌가API용 GZIP: 호환성과 실무 성능페이로드 유형: 무엇이 잘 압축되고 무엇이 아닌가HTTP 헤더와 협상: 올바르게 구성하기HTTP/2, HTTP/3, CDN, 게이트웨이권장 기본값 및 튜닝 플레이북자주 묻는 질문
공유
Koder.ai
Koder로 나만의 앱을 만들어 보세요 지금!

Koder의 힘을 이해하는 가장 좋은 방법은 직접 체험하는 것입니다.

무료로 시작데모 예약
Accept-Encoding
gzip
identity
1–4
8–11
  • GZIP: 기본값으로 5–6 권장
  • 높은 레벨은 보통 크기 감소가 점진적이며, CPU를 크게 올려 p95/p99를 악화시킬 수 있습니다.

  • 잘 압축되는 항목: JSON, GraphQL, XML, HTML, 큰 텍스트 로그
  • “검토 필요”: Protobuf/MessagePack(자주 압축 가능 — 측정 권장)
  • 보통 비추천: JPEG/PNG/WebP, MP4, ZIP/gz, 많은 PDF
  • 일반적 접근은 텍스트 계열 Content-Type에 대해서만 압축을 활성화하고, 이미 압축된 형식에 대해서는 비활성화하는 것입니다.

    Accept-Encoding
    무압축
    Content-Encoding
  • 이중 압축(오리진이 이미 압축했는데 게이트웨이나 CDN이 다시 압축함)
  • 헤더/본문 불일치(Content-Encoding이 설정되어 있지만 본문이 압축되어 있지 않음 또는 그 반대)
  • 잘못된 협상(Accept-Encoding을 무시하거나 클라이언트가 광고하지 않은 인코딩 반환)
  • 프록시/CDN 간섭(헤더를 제거하거나 변경함)
  • 스트림 손상(본문이 잘리거나 Content-Length가 잘못됨)
  • 디버깅 시에는 원시 응답 헤더를 캡처하고 신뢰할 수 있는 도구/클라이언트로 디코딩을 검증하세요.

  • 빠른 롤백 경로 유지(기능 플래그나 게이트웨이 설정으로 압축 비활성화 또는 gzip으로 폴백)
  • 모니터링 항목:
    • 서버 CPU 이용률/포화도
    • p50/p95/p99 레이턴시 및 TTFB
    • 전송 바이트(압축 vs 비압축)
    • 에러/타임아웃 및 클라이언트 디코드 실패
  • 부하에서 테일 레이턴시가 상승하면 레벨을 낮추거나 임계값을 올리거나 더 빠른 코덱(보통 ZSTD)으로 전환하세요.