오픈소스 인사이트
home
오픈소스 기술 동향
home
🚀

Nginx 최적화 "압축 방식만 바꿨는데 성능이 658배?" Gzip Static 적용기

들어가며

오늘은 웹 서버 성능 최적화의 끝판왕, Nginx의 Gzip Static 기능을 공유해보려고 합니다.
웹 서비스를 운영하다 보면 JS, CSS 같은 정적 파일 용량 때문에 고민이 많으시죠?
보통 gzip on; 설정 하나로 해결하시곤 하는데, 과연 그게 최선일까요?
직접 수치로 증명한 결과를 보여드립니다!

실시간 Gzip 압축, 무엇이 문제일까?

우리가 흔히 쓰는 gzip on;'실시간 압축' 방식입니다. 클라이언트가 요청을 보낼 때마다 서버가 파일을 막 압축해서 보내주는 거죠.
문제점: 요청이 몰리면? 서버 CPU가 압축 계산하느라 비명을 지릅니다.
성능 타협: 서버가 너무 힘들까 봐 압축 레벨을 낮게 설정하게 되고, 결국 전송 효율도 떨어지죠.

해결사 등장 Gzip Static 모듈

gzip_static"서버야, 고생하지 마. 내가 미리 압축해둔 파일(.gz) 보낼게!" 하는 방식입니다.
원리: 배포할 때 미리 최상위 레벨(Level 9)로 압축 파일을 만들어둡니다.
장점: Nginx는 계산할 필요 없이 파일만 던져주면 끝! CPU 사용량이 드라마틱하게 줄어듭니다.

직접 해보는 성능 테스트 (The Benchmark)

실제 운영 환경과 유사한 대용량 텍스트 파일(gzip_test.html)을 작성하여 wrk 도구를 이용해
실시간 압축(Gzip on) 환경과 사전 압축(Gzip Static) 환경을 각각 구성하여 동일한 조건에서 부하를 걸어보았습니다.

테스트 환경 및 명령어

대상 파일: gzip_test.html (대용량 텍스트 파일)
부하 조건: 2개 스레드, 100개 동시 연결, 10초간 테스트
명령어: ./wrk -t2 -c100 -d10s -H "Accept-Encoding: gzip" --latency http://localhost/gzip_test.html

실제 터미널 로그 분석

[Case 1] Gzip On (Level 5) 실행 결과
실시간으로 압축을 수행하다 보니 응답 속도(Latency)가 밀리고, 처리량도 초당 400건대에 머뭅니다.
호출 테스트 케이스 : gzip_test.html 파일 내 include 리소스
gzip_test.txt
jquery.js
Running 10s test @ http://localhost/gzip_test.html Latency 212.82ms 56.33ms 408.60ms 84.23% Req/Sec 233.34 42.08 350.00 67.00% 4649 requests in 10.01s, 110.04MB read Requests/sec: 464.61 Transfer/sec: 11.00MB
JavaScript
복사
[Case 2] Gzip Static On 실행 결과
미리 압축된 파일을 전송만 하므로 지연 시간이 ms(밀리초)에서 us(마이크로초) 단위로 뚝 떨어집니다.
처리량은 30만 건으로 폭증합니다.
호출 테스트 케이스 : gzip_test.html 파일 내 include 리소스
gzip_test.txt.gz
jquery.js.gz
Running 10s test @ http://localhost/gzip_test.html Latency 183.78us 78.15us 2.96ms 82.93% Req/Sec 153.73k 3.91k 159.86k 79.50% 3059789 requests in 10.00s, 70.66GB read Requests/sec: 305963.72 Transfer/sec: 7.07GB
JavaScript
복사

성능 비교 결과

항목
실시간 압축 (Dynamic)
사전 압축 (Static)
개선 수치
Nginx 설정
gzip on; / gzip_comp_level 5;
gzip_static on; (Level 9 사전압축)
초당 요청 수 (RPS)
464.61 req/s
305,963.72 req/s
약 658배 증가
평균 지연 시간
212.82 ms
183.78 us (0.18ms)
약 1,150배 지연 감소
최대 지연 시간
408.60 ms
2.96 ms
약 138배 단축
초당 전송량
11.00 MB/s
7.07 GB/s
약 657배 증가
결과 요약
CPU가 압축하느라 병목 발생
CPU 부하 없이 I/O 속도 풀가동

결과 분석

실시간 압축 (Gzip On): 평균 응답 속도가 212ms까지 늘어났고, 초당 464번의 요청만 처리 가능했습니다. 서버 CPU가 압축 연산을 수행하느라 병목이 발생했기 때문입니다.
사전 압축 (Gzip Static): 응답 속도가 무려 183us(마이크로초) 단위로 줄어들었습니다! 초당 처리량은 무려 30만 건을 넘어섰으며, 초당 전송량은 7GB/s에 달합니다.
이 결과는 서버가 압축에 쓰던 CPU 자원을 온전히 데이터 전송에만 집중했을 때 얼마나 강력한 퍼포먼스를 내는지 여실히 보여줍니다.

나도 적용해보기 (Nginx 설정)

해당 기능을 적용하기 위 Nginx 설정 파일의 각 옵션들을 소개합니다!
(단, Nginx 설치 시 http_gzip_static_module이 포함되어 있어야 합니다.)
nginx.conf
http { # //사전 압축 파일(.gz)이 있으면 우선 전송 gzip_static on; # //압축 파일이 없으면 실시간으로라도 압축 (안전장치) gzip on; # //압축에서 제외할 최소 파일 크기 (너무 작은 파일은 압축 효율이 떨어짐) gzip_min_length 1024; # //압축 레벨 (1~9, 숫자가 높을수록 압축률은 좋지만 CPU 점유율 상승) # //보통 5 또는 6이 성능과 리소스 사이의 황금 밸런스이지만, 서버의 CPU 부하를 고려 gzip_comp_level 5; # //압축에 사용할 버퍼 설정 # //기본적으로 시스템 페이지 크기에 따라 자동 설정되나, # //대용량 응답이 많은 경우 명시적으로 지정하여 디스크 I/O를 줄일 수 있습니다. gzip_buffers 16 8k; # //압축을 적용할 파일 형식 (이미지는 효과가 없으므로 텍스트 기반 위주) gzip_types text/plain text/css application/json application/javascript application/xml text/javascript; # //프록시 서버(CDN 등)를 거칠 때도 압축 적용 여부 결정 gzip_proxied any; # //브라우저가 gzip을 지원하는지에 따라 Vary 헤더 추가 # //vary 헤더를 추가하면 Accept-Encoding 헤더가 추가되어 브라우저 캐싱 효율성을 높인다. gzip_vary on; # //오래된 브라우저(IE6 등)는 압축에서 제외 gzip_disable "msie6|Mozilla/4"; }
JavaScript
복사
꿀팁! 배포 전에 미리 호출 대상 정적 리소스를 .gz 압축하여 만들어두는 걸 잊지 마세요!

마치며

테스트 결과가 말해주듯, 정적 리소스가 많은 서비스에서 gzip_static최소의 비용으로 최대의 효과를 내는 최적화 기법입니다.
1.
CPU 자원 절약: 서버가 더 중요한 비즈니스 로직(WAS 연산 등)에 집중할 수 있어요.
2.
안정성 향상: 갑작스러운 트래픽 폭주에도 서버가 끄떡없습니다.
3.
지연 시간 단축: 유저는 0.1ms 만에 압축된 데이터를 받아볼 수 있습니다.
여러분의 서버는 지금 실시간으로 고생하고 있진 않나요? 지금 바로 gzip_static을 검토해보세요!
명주호 프로
오픈소스사업부 오픈소스기술팀
에스코어에서 미들웨어 엔지니어로 근무하며, 삼성 그룹사를 비롯한 국내 주요 대기업과 공공기관의 미들웨어 설계 및 기술지원을 담당하고 있어요