- 들어가며 — 마지막 칸이 채워졌다
- 지원 매트릭스 — zstd와 사전 압축은 상황이 다르다
- zstd가 실제로 사 주는 것 — 숫자는 조건과 함께
- 서버 쪽은 아직 비대칭이다
- 다음 단계 — RFC 9842 압축 사전 전송
- 실측 수치 — 정적 흐름과 동적 흐름
- 사전이 답이 아닐 때
- 실무 판단
- 마치며
- 참고 자료
들어가며 — 마지막 칸이 채워졌다
2026년 2월 11일에 나온 Safari 26.3의 릴리스 노트에는 이런 한 줄이 있습니다. 원문 그대로 옮기면 — "Added support for Zstandard content encoding in Safari 26.3 for iOS, iPadOS, visionOS, and macOS 26.3." (Apple 릴리스 노트)
이 한 줄로 상황이 바뀝니다. Content-Encoding: zstd는 Chrome 123(2024년 3월), Firefox 126(2024년 5월)이 먼저 지원했고, 남은 큰 조각이 Safari였습니다. 이제 3대 브라우저 엔진(Blink, Gecko, WebKit)이 전부 zstd로 압축된 HTTP 응답을 받습니다. HTTP 전송 압축의 표준 선택지가 gzip, brotli에 이어 셋으로 늘어난 게 실질적으로 완성된 셈입니다.
물론 캐비앳부터 적어 두겠습니다. WebKit 블로그에 따르면 Safari 26.3의 zstd는 iOS/iPadOS/visionOS 26.3과 macOS Tahoe 26.3에서 동작하고, 구형 macOS 위에서 도는 Safari 26.3에서는 동작하지 않습니다(시스템 네트워킹 스택 의존). 그래서 caniuse 집계도 Safari 26.3을 "macOS 26.3 이상 필요"라는 주석과 함께 부분 지원으로 분류합니다 — 글 작성 시점 조회 기준으로 전면 지원 브라우저 점유율 약 79.5%, 부분 지원 약 2.1%입니다.
그래도 도입 리스크 자체는 낮습니다. 압축은 Accept-Encoding 협상으로 결정되므로, zstd를 못 받는 클라이언트에는 brotli나 gzip으로 자동 폴백됩니다. 켠다고 깨질 곳은 없고, 안 켜면 이득도 없습니다.
지원 매트릭스 — zstd와 사전 압축은 상황이 다르다
MDN 브라우저 호환성 데이터 기준으로 정리하면 이렇습니다.
| 기능 | Chrome | Firefox | Safari |
|---|---|---|---|
Content-Encoding: zstd | 123 (2024-03) | 126 (2024-05) | 26.3 (2026-02) |
dcb / dcz (사전 압축, RFC 9842) | 130 (2024-10) | 미지원 | 미지원 |
윗줄이 이번에 완성된 이야기고, 아랫줄이 이 글 후반부의 이야기입니다. 사전 압축 전송은 2025년 9월에 RFC 9842로 발행됐지만(저자는 Google의 P. Meenan, Shopify의 Y. Weiss) 아직 Chromium 계열만 출하했습니다. 다만 Mozilla는 공식 입장 positive, WebKit은 support를 밝혀 둔 상태라, 반대 때문에 막혀 있는 것은 아닙니다.
zstd가 실제로 사 주는 것 — 숫자는 조건과 함께
zstd 프로젝트가 README에 공개한 자체 벤치마크를 조건 그대로 옮깁니다. Core i7-9700K @ 4.9GHz, Ubuntu 24.04, gcc 14.2.0, lzbench(인메모리), Silesia 코퍼스 — 즉 프로젝트 자체 측정이고, 디스크·네트워크 없이 순수 CPU 처리량을 잰 수치입니다.
| 압축기 (레벨 1 계열) | 압축률 | 압축 속도 | 해제 속도 |
|---|---|---|---|
| zstd 1.5.7 -1 | 2.896 | 510 MB/s | 1550 MB/s |
| brotli 1.1.0 -1 | 2.883 | 290 MB/s | 425 MB/s |
| zlib 1.3.1 -1 | 2.743 | 105 MB/s | 390 MB/s |
이 표에서 읽을 것은 순위가 아니라 격차의 성격입니다. 같은 "빠른 레벨" 대역에서 zstd는 zlib보다 압축이 약 5배, 해제가 약 4배 빠르면서 압축률은 오히려 높습니다. 그래서 zstd의 단골 사용처는 동적 응답의 on-the-fly 압축입니다 — WebKit 블로그도 정확히 이 프레임으로 소개합니다. brotli는 보통 빌드 타임에 정적 자산을 최고 레벨로 미리 압축해 두는 쪽에 쓰고, 실시간으로 압축해야 하는 API 응답·HTML에는 zstd가 CPU 예산 대비 유리하다는 것입니다. 참고로 이 표는 레벨 1 기준이라 "brotli 최고 레벨 대비 압축률" 같은 주장은 여기서 도출되지 않습니다 — 알고리즘 내부(LZ77, ANS, Huffman)가 궁금하면 압축 알고리즘 깊이 파기 편을 보세요.
HTTP 밖에서는 이미 검증이 끝난 교체입니다. Discord는 게이트웨이(WebSocket) 압축을 zlib 스트리밍에서 zstd 스트리밍으로 바꾸면서, MESSAGE_CREATE 페이로드의 압축률이 6에서 10 근처로 오르고 평균 크기가 270바이트에서 166바이트로 줄었다고 자체 측정치를 공개했습니다(2024년 롤아웃). 그들이 말하는 "게이트웨이 대역폭 약 40% 절감"은 zstd 단독이 아니라 별도의 passive sessions 최적화와 합산된 수치라는 점은 원문에 명시돼 있습니다.
라이브러리 자체의 릴리스 상태도 짚어 두면 — 최신 릴리스는 v1.5.7(2025-02-19)이고, dev 브랜치 CHANGELOG에는 v1.6.0 항목(레거시 포맷 지원 기본 비활성화)이 준비돼 있지만 2026년 7월 17일 현재 태그도 GitHub 릴리스도 없습니다.
서버 쪽은 아직 비대칭이다
브라우저가 다 받는다고 끝이 아닙니다. 보내는 쪽 지형은 이렇습니다(2026-07 기준, 각 프로젝트 공식 문서·체인지로그 확인).
- nginx — 공식 zstd 모듈이 없습니다. 공식 문서 모듈 목록에 zstd가 등장하지 않고, 쓰려면 서드파티 모듈을 직접 빌드해야 합니다.
- Apache httpd — 2.4.x CHANGES에 zstd 항목이 없습니다. 공식은 mod_brotli까지입니다.
- Caddy —
encode디렉티브가 zstd를 지원합니다. - Node.js — v23.8.0(2025-02-13)부터
node:zlib에 zstd 압축·해제 API가 들어갔습니다. 앱 레벨에서 직접 처리할 수 있습니다. - CDN — Cloudflare는 전 플랜에서 Zstandard를 지원하고, Free 플랜은 기본 압축이 Zstandard입니다(브로틀리·zstd는 응답 최소 50바이트 조건).
요약하면, 오리진이 nginx/httpd라면 오늘 가장 짧은 경로는 CDN에서 켜는 것입니다. 두 주류 웹서버에 공식 모듈이 없다는 사실이 현재 zstd 배포의 실질적 병목이고, "브라우저 지원 완성"과 "서버 생태계 완성" 사이의 시차가 이 주제의 현재 위치입니다.
다음 단계 — RFC 9842 압축 사전 전송
zstd 지원 완성이 1막이라면, 2막은 사전(dictionary) 압축입니다. 아이디어는 단순합니다. 압축 알고리즘은 "이미 본 데이터"를 참조해 다음 데이터를 줄이는데, 브라우저는 이미 많은 걸 갖고 있습니다 — 어제 받은 JS 번들, 같은 사이트의 다른 HTML. 그걸 사전으로 쓰면 사실상 델타만 전송하면 됩니다.
RFC 9842가 정의하는 흐름을 개념 예시로 그리면 이렇습니다.
# 1) 첫 방문 - 서버가 이 응답을 사전으로 등록하라고 알린다
GET /js/app.v133.js
<- 200 OK
<- Content-Encoding: br
<- Use-As-Dictionary: match="/js/app*.js"
# 2) 다음 방문 - 브라우저가 보유한 사전의 해시를 광고한다
GET /js/app.v134.js
-> Available-Dictionary: :pZGm1Av0IEBKARczz7exkNYsZb8LzaMrV7J32a2fFG4=:
-> Accept-Encoding: gzip, br, zstd, dcb, dcz
# 3) 서버는 그 사전으로 압축된 델타만 보낸다
<- 200 OK
<- Content-Encoding: dcb
별도 사전 리소스를 <link rel="compression-dictionary">로 내려 주는 경로도 있습니다. 새 콘텐츠 인코딩은 두 가지로, dcb는 4바이트 매직 넘버와 사전의 SHA-256 해시(32바이트) 뒤에 Shared Brotli 스트림이 오는 포맷이고(클라이언트는 최대 16MB 윈도 해제 의무), dcz는 zstd의 skippable frame으로 설계된 40바이트 헤더 뒤에 사전 적용 zstd 스트림이 오는 포맷입니다 — 클라이언트는 8MB 또는 사전 크기의 1.25배 중 큰 쪽(상한 128MB)까지의 윈도를 지원해야 합니다. 캐시 가능한 응답이라면 Vary: accept-encoding, available-dictionary가 필수입니다 — 사전이 다른 클라이언트에게 잘못 서빙되는 것을 막기 위해서입니다. 세부는 RFC 9842 4·5장에 있습니다.
실측 수치 — 정적 흐름과 동적 흐름
숫자는 두 부류로 나눠 봐야 합니다. 출처와 조건을 붙입니다.
정적 흐름(이전 버전을 사전으로). RFC 공저자 Meenan이 공개한 테스트 모음이 기준점입니다. 저자 자체 측정이고, brotli CLI 레벨 5, "사전 = 같은 리소스의 이전 버전" 조건입니다.
- YouTube 데스크톱 플레이어 JS(10MB, 비압축): brotli 단독 1.8MB → 두 달 전 버전을 사전으로 쓰면 384KB(78% 감소). 주 단위 릴리스 간격이면 172KB(90% 감소).
- CNN 헤더 번들(278KB): brotli 단독 90KB → 1년 전 버전을 사전으로 2KB(98% 감소).
- Wikipedia처럼 텍스트 위주로 이미 잘 압축되는 페이지는 개선 폭이 훨씬 작았다고 같은 문서에 적혀 있습니다.
동적 흐름(경로 전용 커스텀 사전). 여기엔 실배포 수치가 있습니다. Google 검색은 검색결과 페이지 HTML에 공유 brotli 사전을 배포하고 결과를 Chrome 블로그에 공개했습니다(2025-05-14, 벤더 자체 측정). 대표 샘플로 사전을 만들고 하루에도 여러 번 갱신하는 자동 파이프라인을 돌린 조건에서 —
- 전체 Chrome 사용자 기준 HTML 페이로드 평균 23% 감소. 이 평균에는 사전이 없는 첫 방문 사용자가 포함됩니다.
- 사전이 적중한 응답만 보면 50%에 가까운 감소.
- 체감 지표로는 LCP 개선이 전체 1.7%, 고지연 네트워크에서 최대 9%.
마지막 줄이 이 글에서 제일 정직한 숫자라고 생각합니다. 전송 바이트가 수십 퍼센트 줄어도, 세계에서 가장 최적화된 페이지의 LCP는 1.7% 좋아집니다. 압축 절감률과 체감 속도는 등가가 아닙니다 — 특히 대역폭이 병목이 아닌 환경에서는요. 거꾸로 고지연·저대역 환경에서 최대 9%라는 건, 이 기법의 가치가 사용자 분포에 따라 크게 달라진다는 뜻이기도 합니다.
사전이 답이 아닐 때
균형을 위해 실패 사례도 하나. Discord는 위의 zstd 전환 과정에서 사전도 시도했습니다 — 12만 개의 익명화된 메시지로 JSON용·ETF용 사전 두 개를 훈련시켰습니다. 오프라인 평가에서는 소형 페이로드가 636바이트에서 187바이트로 줄어 유망해 보였지만(사전 없이는 466바이트), 프로덕션에서는 결과가 엇갈렸습니다. 2.5MB짜리 READY 페이로드는 사전을 써도 약 600바이트밖에 더 못 줄였고, MESSAGE_CREATE는 오히려 나빠졌습니다. 결론은 사전 포기 — "사전이 주는 소폭의 압축 개선은 게이트웨이와 클라이언트에 더해지는 복잡도에 못 미쳤다"는 게 그들의 정리입니다.
이유는 구조적입니다. Discord의 연결은 스트리밍 압축 컨텍스트가 살아 있어서, 연결이 이어지는 동안 압축기가 이미 "지난 데이터로 학습"을 합니다. 사전이 돕는 구간은 스트림의 첫 몇 KB뿐입니다. zstd 프로젝트 문서도 같은 말을 합니다 — 사전 이득은 작은 데이터의 첫 몇 KB에 집중되고, 만능 사전은 없으며, 데이터 타입마다 따로 훈련해야 합니다.
HTTP 쪽 사전 압축(RFC 9842)에도 고유 비용이 있습니다.
- 운영 파이프라인. Google 사례의 전제는 하루 여러 번 사전을 재생성·재배포하는 자동화입니다. 콘텐츠가 바뀌는데 사전이 낡으면 이득이 줄어듭니다. 빌드·서빙 경로에 사전 버저닝이 추가됩니다.
- 프라이버시 규정. 사전 해시가 추적 쿠키로 악용될 수 있어서, RFC 10장은 클라이언트가 사전을 쿠키와 동일하게 취급하도록 요구합니다 — 쿠키 수준(또는 그 이상)의 파티셔닝, 쿠키 삭제 시 사전도 삭제. 즉 사전 적중률은 쿠키 수명을 넘지 못합니다.
- 보안 제약. 혼합 소스 압축 공격(CRIME/BREACH 계열, RFC 7457) 고려가 사전에도 그대로 적용됩니다 — 사전에 사용자 데이터를 넣으면 안 되고(Discord도 훈련 데이터를 익명화했습니다), 사전 매칭은 same-origin으로 제한되며 교차 출처는 CORS 통과가 필수입니다.
- 브라우저 커버리지. 다시, 현재는 Chromium 계열뿐입니다. Firefox/Safari 사용자용 일반 압축 경로는 계속 유지해야 하므로, 사전 압축은 "추가 파이프라인"이지 대체가 아닙니다.
실무 판단
지금 켤 것 — Content-Encoding: zstd. 협상 기반 폴백 덕에 리스크가 낮고, 브라우저 커버리지는 이번 Safari 26.3으로 사실상 채워졌습니다. CDN 뒤에 있다면 설정 스위치 수준입니다. 오리진에서 직접 하려면 nginx/httpd 공식 모듈 부재가 현실적 장애물이니, Caddy·Node 앱 레벨·CDN 중 자기 스택에 맞는 경로를 고르면 됩니다. 동적 응답(on-the-fly)이 핵심 사용처고, 정적 자산 프리컴프레스는 기존 brotli 파이프라인을 유지해도 됩니다.
계산해 보고 결정할 것 — dcb/dcz. 재방문 비중이 높고 JS 번들이 크며 릴리스가 잦은 서비스라면, Chromium 점유율만큼의 절감으로도 계산이 설 수 있습니다. 위 실측처럼 델타 전송은 자릿수가 다른 절감을 주니까요. 단, 사전 생성·버저닝 파이프라인과 이중 서빙 경로를 감당할 팀이어야 하고, 절감 바이트가 아니라 자기 서비스의 체감 지표(LCP 등)로 이득을 검증해야 합니다 — Google조차 전체 LCP 개선은 1.7%였습니다.
하지 말 것. 트래픽이 작거나 사용자 재방문이 드문 사이트가 사전 인프라부터 짓는 것. 스트리밍 압축 컨텍스트가 이미 있는 커스텀 프로토콜에 사전을 얹는 것(Discord의 교훈). 그리고 벤더 절감률을 자기 서비스의 성능 개선으로 등치하는 것.
마치며
정리하면 이렇습니다. Safari 26.3(2026-02-11)으로 Content-Encoding: zstd의 브라우저 퍼즐은 채워졌고, 남은 비대칭은 서버 생태계(두 주류 웹서버의 공식 모듈 부재)입니다. 그 다음 단계인 RFC 9842 사전 압축은 표준화(2025-09)와 실배포 검증(Google 검색, 벤더 자체 측정 평균 23% 페이로드 감소)까지 끝났지만, 브라우저는 아직 Chromium뿐이고 운영 비용과 프라이버시 규정이 실재합니다. zstd는 오늘 켜고, 사전은 자기 트래픽으로 계산부터 하세요. 압축률은 수단이고, 지표는 언제나 사용자 쪽에 있습니다.
참고 자료
- Safari 26.3 Release Notes — Apple Developer
- WebKit Features in Safari 26.3 — webkit.org
- RFC 9842 — Compression Dictionary Transport
- Content-Encoding — MDN (브라우저 호환성 표)
- zstd (Zstandard) content-encoding — caniuse
- facebook/zstd — Benchmarks (프로젝트 자체 측정)
- Compression dictionary transport examples — WICG (저자 자체 측정)
- How Google Search made their results pages 23% smaller — Chrome for Developers (벤더 자체 측정)
- How Discord Reduced Websocket Traffic by 40% — Discord (벤더 자체 측정)
- Zstd Content-Encoding — Chrome Platform Status
- Compression dictionary transport — Chrome Platform Status
- Mozilla standards-positions #771 (positive) · WebKit standards-positions #160 (support)
- Node.js v23.8.0 — node:zlib zstd 지원
- Cloudflare compression 문서 · Caddy encode 디렉티브
- 압축 알고리즘 깊이 파기 — LZ77, zstd, brotli, ANS, Huffman (관련 글)
현재 단락 (1/74)
2026년 2월 11일에 나온 Safari 26.3의 릴리스 노트에는 이런 한 줄이 있습니다. 원문 그대로 옮기면 — "Added support for Zstandard conte...