--- id: cs-compression-algorithms title: Compression — gzip / brotli / zstd / lz4 category: Coding status: draft source_trust_level: B verification_status: conceptual created_at: 2026-05-09 updated_at: 2026-05-09 tags: [cs, compression, vibe-coding] tech_stack: { language: "TS / Various", applicable_to: ["Backend", "Frontend"] } applied_in: [] aliases: [gzip, brotli, zstd, lz4, snappy, deflate, compression ratio] --- # Compression Algorithms > Network / disk 압축. **gzip (legacy), brotli (web), zstd (modern), lz4 (속도)**. Trade-off: ratio vs CPU. Per use case. ## 📖 핵심 개념 - Ratio: 작을수록 좋음. - Speed: compress / decompress 별. - Memory: small footprint. - Streaming: 점진 압축. ## 💻 코드 패턴 ### 비교 (대략) ``` Algorithm Ratio CPU comp CPU decomp Use case gzip 3-5x middle fast legacy web, log brotli 5-7x slow-ish fast web (HTTP) zstd 4-6x fast very fast modern default lz4 2-3x very fast very fast memory cache, snap snappy 2-3x very fast very fast big data (Cassandra) xz 5-10x slow slow backup zlib 3-5x middle fast legacy ``` ### Node 사용 ```ts import zlib from 'node:zlib'; import { promisify } from 'node:util'; // gzip const gzip = promisify(zlib.gzip); const gunzip = promisify(zlib.gunzip); const compressed = await gzip(Buffer.from('hello'.repeat(1000))); const decompressed = await gunzip(compressed); // Brotli const compressed = await promisify(zlib.brotliCompress)(buf); const decompressed = await promisify(zlib.brotliDecompress)(compressed); ``` ### Streaming ```ts import { createGzip } from 'node:zlib'; import { pipeline } from 'node:stream/promises'; import fs from 'node:fs'; await pipeline( fs.createReadStream('input.txt'), createGzip({ level: 6 }), fs.createWriteStream('output.txt.gz'), ); ``` ### zstd (modern, recommend) ```bash yarn add @mongodb-js/zstd # 또는 node-zstandard ``` ```ts import zstd from '@mongodb-js/zstd'; const compressed = await zstd.compress(buffer, 3); // level 1-22 const decompressed = await zstd.decompress(compressed); ``` ### HTTP — gzip / brotli (자동) ```ts // Express import compression from 'compression'; app.use(compression({ level: 6, threshold: 1024, // > 1KB 만 filter: (req, res) => { const t = res.getHeader('Content-Type'); return /text|json|javascript|css|svg/.test(String(t)); }, })); ``` ```ts // Hono (modern, brotli + gzip) import { compress } from 'hono/compress'; app.use(compress({ encoding: 'br' })); // 또는 gzip ``` → 자동 Accept-Encoding 검사 + 적절 algorithm. ### nginx ```nginx gzip on; gzip_types text/css application/javascript application/json; gzip_min_length 1024; gzip_comp_level 6; brotli on; brotli_types text/css application/javascript application/json; brotli_comp_level 6; ``` → Brotli 가 web 표준 (3-5% 더 작음 vs gzip). ### Pre-compression (static) ```bash # Build 시 압축 — runtime CPU 안 씀 brotli -k -q 11 dist/*.js dist/*.css # 최강 압축 gzip -k -9 dist/*.js dist/*.css # 또는 vite plugin ``` ```ts // vite.config.ts import compression from 'vite-plugin-compression'; plugins: [ compression({ algorithm: 'gzip', ext: '.gz' }), compression({ algorithm: 'brotliCompress', ext: '.br' }), ]; ``` ```nginx # Pre-compressed serve gzip_static on; brotli_static on; ``` → Build 시 1번 압축 + nginx 가 그냥 serve. ### 압축 가능한 vs 불가능한 ``` Compress 잘 됨: Text (JSON, XML, HTML, CSS, JS, log, code) Compress 안 됨: Image (JPEG, PNG, WebP — 이미 압축) Video (MP4, WebM) Audio (MP3, AAC) Binary (PDF, archive) Random / encrypted → Image / video 도 압축 시도 = CPU 만 쓰고 더 작아지지도 않음. ``` ### Database column (Postgres TOAST) ``` TEXT / BYTEA > 8KB → 자동 PGLZ 압축. LZ4 도 옵션 (Postgres 14+). ALTER TABLE x ALTER COLUMN data SET COMPRESSION lz4; ``` → Disk 절약. Query speed 거의 영향 X. ### Compression in storage ``` Parquet: Snappy (default) / gzip / zstd / brotli ORC: Snappy / zlib / lzo ClickHouse: lz4 / zstd Cassandra: Snappy / lz4 / zstd RocksDB: Snappy / lz4 / zstd ``` → zstd 가 modern best (ratio + speed). ### Network — sockets ```ts // WebSocket compression const ws = new WebSocket(url, { perMessageDeflate: true }); ``` → 큰 message 자주 = enable. ### Brotli vs gzip (web specific) ``` Brotli static dictionary = HTML / JS / CSS 자주 단어. 같은 size 파일 → brotli 가 5-15% 작음. → Modern web = brotli + gzip fallback. ``` ### Compression bomb (보안) ``` 1KB compressed → 1GB decompressed. Server 가 검사 없이 decompress = OOM. → Max decompressed size limit. ``` ```ts import { gunzipSync } from 'node:zlib'; const MAX_SIZE = 100 * 1024 * 1024; // 100MB const decompressed = gunzipSync(buf, { maxOutputLength: MAX_SIZE }); ``` ### LZ4 (memory cache) ```ts import LZ4 from 'lz4js'; const compressed = LZ4.compress(buf); const decompressed = LZ4.decompress(compressed); ``` → 매우 빠름 — Redis 가 사용 가능. ### Snappy (big data, Hadoop / Cassandra) - 매우 빠른 compress / decompress. - Ratio 약함 (2-3x). - Big data scenarios. ### 압축 level 결정 ``` gzip / brotli / zstd: 1 (fast) - 9/11/22 (slow + smaller) Real-time stream: level 1-3 HTTP 응답: 6 (default) Static asset: 11 (max — pre-build) Backup: max ``` ### 측정 ```ts const original = data.length; const t0 = Date.now(); const compressed = await zstd.compress(data, 3); const t1 = Date.now(); const decompressed = await zstd.decompress(compressed); const t2 = Date.now(); console.log({ original, compressed: compressed.length, ratio: (original / compressed.length).toFixed(2), compressMs: t1 - t0, decompressMs: t2 - t1, }); ``` ### Dictionary compression (큰 절약) ``` 같은 schema JSON 매번 보내면 — 같은 키 반복. Pre-built dictionary 로 더 작게. zstd 가 dict mode 지원: zstd --train *.json -o dict zstd -D dict input.json ``` → 50-80% 더 작아짐 가능. ## 🤔 의사결정 기준 | 사용 | 추천 | |---|---| | HTTP 응답 (실시간) | brotli (level 4-6) + gzip fallback | | Static asset (build) | brotli max + gzip max pre-compressed | | Database column | zstd / lz4 | | Memory cache | lz4 / snappy | | Backup | zstd / xz | | Streaming pipe | zstd / lz4 | | Big data analytic | snappy / zstd | | Real-time game | lz4 | ## ❌ 안티패턴 - **이미 압축된 file 다시**: CPU 낭비. 검사 후. - **Compress small data (< 1KB)**: header overhead. - **Decompression bomb 무 limit**: OOM 공격. - **Static asset 매 요청 압축**: pre-compress. - **Brotli only — gzip fallback X**: 옛 client 깨짐. - **Level 22 real-time**: latency 큼. - **모든 Content-Type 압축**: image 등 안 줄어듦. ## 🤖 LLM 활용 힌트 - Web: brotli + gzip fallback (자동 lib). - Storage: zstd (modern). - Speed-critical: lz4 / snappy. - Pre-compress static. ## 🔗 관련 문서 - [[Web_HTTP_Cache_Headers]] - [[Mobile_App_Size_Optimization]] - [[Frontend_Image_Optimization]]