ShopperCove
Menu
All writingBlogTopicsCategoriesAboutRSS
Blog
Categories
Observability & SRE62All categories
About

Plate 24

  1. Blog
  2. /Observability & SRE

zlib vs gzip.compress Same Level: Localhost Lab

Hands-on zlib.compress vs gzip.compress same-level (6) stdlib bake-off: real MB/s and sizes, measured on Linux localhost in this hands-on lab for SREs.

Aditya Challa·30 September 2026·4 min read

Lab
On this page
  1. Intro — what this post promises
  2. Arms
  3. Lab topology
  4. Lead table — 1 MiB (p50)
  5. Scale sketch (compress MB/s)
  6. What gzip adds
  7. Streaming note
  8. Reading it
  9. Level fairness
  10. Wire format reminder
  11. Pitfalls
  12. Reproduce
  13. Limits
  14. Takeaway

Intro — what this post promises

In-memory compress/decompress of a compressible fixture via zlib.compress / zlib.decompress vs gzip.compress / gzip.decompress at the same level (6). This lab reports MB/s and output size on Linux localhost.

It is not the multi-codec zstd/gzip/lz4 bake-off (lab 33) and not nginx gzip toggles (lab 20). Here the question is only: Python stdlib zlib vs gzip wrappers.

Related links:

  • zstd vs gzip lz4 compression localhost lab
  • nginx gzip on vs off localhost lab
  • queue vs deque handoff localhost lab
  • stringio vs list join localhost lab
  • groupby vs manual localhost lab
  • methodcaller vs getattr localhost lab
  • hmac compare digest localhost lab
  • argparse vs sys argv localhost lab

Lab honesty (1 Oct 2026 IST): Python 3.13.5. Affiliates: 0. No Docker. Level 6. Fixture = repeating JSON-ish lines (highly compressible).

Verdict up front (1 MiB): gzip.compress ~335.4 MB/s (out 3661 B); zlib.compress ~320.0 MB/s (out 3649 B); decompress gzip ~994.4 / zlib ~905.3 MB/s. Gzip adds a fixed ~12 B header/trailer overhead on this box.


Arms

ArmAPI
zlib.compress(data, 6)raw DEFLATE container
gzip.compress(data, compresslevel=6)gzip framing around zlib
zlib.decompress / gzip.decompressmatching decode

Lab topology

sizes: 256 KiB · 1 MiB · 4 MiB · level=6 · 7 rounds · p50
metric: MB/s = in_bytes / p50_s / 1024² (decompress vs original size)

Script: lab-evidence/102-zlib-vs-gzip-compress/results/run_lab.py.


Lead table — 1 MiB (p50)

ArmMB/sout bytesratio
gzip.compress335.436610.0035
zlib.compress320.036490.0035
gzip.decompress994.4——
zlib.decompress905.3——

Gzip overhead vs zlib blob: 12 bytes (header + CRC trailer). Throughput is in the same ballpark — framing cost is tiny next to DEFLATE work.


Scale sketch (compress MB/s)

Sizezlibgzipoverhead B
256 KiB330.3343.812
1 MiB320.0335.412
4 MiB306.7319.912

What gzip adds

gzip.compress is zlib DEFLATE plus a gzip header and CRC32/ISIZE trailer. Use gzip when peers expect .gz / HTTP Content-Encoding: gzip. Use raw zlib (or raw DEFLATE) when you own both ends and want a smaller envelope (e.g. some wire protocols).


Streaming note

This lab uses one-shot compress/decompress on full buffers. Chunked compressobj / GzipFile changes memory profile and can change throughput — re-measure if your pipeline is streaming.


Reading it

  • Same level ⇒ nearly identical compress rates; pick the container, not the mythical faster twin.
  • Decompress is several× compress here (compressible payload).
  • Tiny fixed overhead matters more on small blobs than on multi‑MiB ones.
  • For codec shopping (zstd/lz4), go to lab 33 — not this post.

Level fairness

Always pin the same compresslevel (here 6, zlib/gzip default band). Comparing zlib-1 to gzip-9 is a common blog mistake and says nothing useful about framing overhead.


Wire format reminder

HTTP Content-Encoding: gzip, .gz files on disk, and many CLIs speak gzip. Some databases and custom RPCs prefer zlib or raw DEFLATE. Matching the peer’s expected magic bytes matters more than the ~tens of MB/s delta on this box.


Pitfalls

  • Comparing zlib level 6 to gzip level 9 (unfair).
  • Forgetting gzip framing when a client expects zlib-only (or vice versa).
  • Using this highly repetitive fixture as a ratio benchmark for “typical” traffic.
  • Conflating Python API speed with nginx gzip filter cost (lab 20).

Reproduce

python3 lab-evidence/102-zlib-vs-gzip-compress/results/run_lab.py

Evidence: summary.json, summary.txt.


Limits

One Linux box. Synthetic repeating JSON lines (very compressible). Level fixed at 6. Not streaming zlib.compressobj / GzipFile chunked APIs.


Takeaway

At 1 MiB level 6, gzip.compress ~335.4 MB/s and zlib.compress ~320.0 MB/s — choose gzip for interoperability, zlib for a leaner envelope (+12 B for gzip here).

zlib.compressgzip.compressdeflategzip headerpython zliblocalhost labsremb/s

Lab evidence

What I found running this

Lab 1 Oct 2026 IST. Python 3.13.5. level=6. 1MiB: gzip_compress 335.4 MB/s out=3661; zlib_compress 320.0 out=3649; overhead 12B. Not lab 33 multi-codec / lab 20 nginx. Affiliates: 0. Evidence: lab-evidence/102-zlib-vs-gzip-compress/.

Notes when a lab post goes up

Occasional email for new hands-on reviews. No sequence and no sponsors.

Related links

  • Plate 88

    mmap Write vs pwrite Region: Localhost Lab

    Hands-on mmap MAP_SHARED write+msync vs pwrite region update: real MB/s with durability labels, measured on Linux localhost in this hands-on lab for SREs.

    Observability & SRE · 1 Oct 2026

  • Plate 12

    islice vs list Slice Windows: Localhost Lab

    Hands-on itertools.islice vs list slice window lab: real ops/s taking ranges from sequences, measured on Linux localhost in this hands-on lab for SREs.

    Observability & SRE · 1 Oct 2026

  • Plate 07

    heapq.merge vs sorted(chain): Localhost Lab

    Hands-on heapq.merge vs sorted(chain) multi-way merge: real records/s on pre-sorted lists, measured on Linux localhost today in this hands-on lab for SREs.

    Observability & SRE · 1 Oct 2026

On this page

  1. Intro — what this post promises
  2. Arms
  3. Lab topology
  4. Lead table — 1 MiB (p50)
  5. Scale sketch (compress MB/s)
  6. What gzip adds
  7. Streaming note
  8. Reading it
  9. Level fairness
  10. Wire format reminder
  11. Pitfalls
  12. Reproduce
  13. Limits
  14. Takeaway
All writingBlogCategoriesTopicsAboutPrivacyRSS

© 2026 ShopperCove