Docker
Nginx gzip과 Brotli를 이미지 응답에 켠 뒤 되돌린 비교 노트
텍스트 압축은 효과가 있었지만 이미지까지 압축해 CPU만 늘린 경험을 바탕으로 Nginx 압축 대상을 비교했습니다.
용량을 줄이면 모두 빨라질 줄 알았다
응답 크기 지표를 낮추려고 Nginx에 gzip을 켰다. HTML과 JSON은 확실히 작아졌지만, 트래픽이 많은 이미지 경로에서도 압축 CPU 사용량이 함께 올랐다. JPEG와 WebP는 이미 압축된 형식이라 다시 gzip해도 줄어드는 양이 거의 없었다.
확인할 때는 브라우저 네트워크 탭만 보지 않고 헤더와 실제 크기를 같이 기록했다.
curl -sS -H 'Accept-Encoding: gzip' -D /tmp/headers -o /tmp/body https://example.com/api/items
awk 'BEGIN{IGNORECASE=1} /^content-(encoding|length):/' /tmp/headers
wc -c /tmp/body
콘텐츠 유형별 결과
| 대상 | 압축 전 기대 | 적용 판단 |
|---|---|---|
| HTML, CSS, JS | 반복 문자열이 많음 | gzip 또는 Brotli 적용 |
| JSON, SVG | 텍스트 비중이 큼 | 적용 |
| JPEG, PNG, WebP | 이미 압축됨 | 제외 |
| ZIP, PDF | 파일 내부 압축 여부가 다양함 | 측정 후 결정 |
Brotli는 정적 자산에 더 좋은 압축률을 보였지만, 동적 응답까지 높은 quality로 처리하면 CPU 비용이 커질 수 있다. 운영에서는 먼저 낮은 quality로 측정하고, 정적 파일은 빌드 단계에서 미리 생성하는 쪽을 택했다.
gzip on;
gzip_types text/plain text/css application/javascript application/json image/svg+xml;
gzip_min_length 1024;
gzip_vary on;
설정 반영 뒤에는 캐시가 이전 헤더를 보여줄 수 있어 새 URL과 curl을 함께 사용했다. Vary: Accept-Encoding이 빠지면 압축 지원 여부가 다른 클라이언트 사이에서 캐시가 섞일 수 있다는 점도 확인했다.
측정 체크리스트
-
Content-Encoding과Content-Length를 실제 응답에서 확인한다 - 압축 전후의 p95 응답 시간과 CPU를 같이 본다
- 이미 압축된 MIME 타입은 기본 제외한다
- CDN이 있다면 원본과 캐시 응답 헤더를 따로 확인한다
- 설정 변경 후 Nginx 문법 검사를 실행한다
sudo nginx -t
sudo systemctl reload nginx
이번 비교에서 얻은 결론은 “압축을 켠다”가 아니라 “텍스트 응답에만, 측정 가능한 수준으로 켠다”였다. 전송량 한 지표만 보고 최적화하면 서버 비용이라는 다른 청구서를 놓치게 된다.