Python gzip: Compress .gz Files

Published on: August 17, 2026
Reading time: 4 minutes
Row of colorful office binders neatly arranged on a shelf, ideal for organization concepts.

The Python gzip module reads and writes GZIP streams through an interface that resembles ordinary files. It uses DEFLATE through zlib and provides in-memory helpers, the GzipFile class, text wrappers, and a small command-line interface.

GZIP is widely supported by Unix tools, web servers, data pipelines, and distribution formats. It compresses one logical stream rather than acting as a multi-file container. To preserve a directory tree, applications commonly create a TAR archive and then compress that stream with GZIP.

When gzip is appropriate

Use GZIP for logs, JSON Lines, CSV exports, HTTP payloads, and backups containing one stream. For lower-level DEFLATE control, see Python zlib. When final size matters more than speed, compare it with Python lzma.

Compress bytes in one call

import gzip

data = ("access record\n" * 2000).encode("utf-8")
compressed = gzip.compress(data, compresslevel=6)
restored = gzip.decompress(compressed)

assert restored == data
print(len(data), len(compressed))

These helpers keep the complete input and output in memory. In Python 3.14, gzip.compress() defaults to mtime=0, making the result independent of the creation time. Pass mtime=None to store the current timestamp.

Create reproducible output

Reproducible builds require identical content to produce identical bytes. A varying header timestamp prevents that. The convenience function now favors deterministic output:

import gzip
import hashlib

artifact = gzip.compress(b"version=1\n", mtime=0)
print(hashlib.sha256(artifact).hexdigest())

When constructing GzipFile directly, set mtime=0 explicitly if this property matters.

Write compressed text

import gzip

with gzip.open("events.log.gz", "wt", encoding="utf-8", compresslevel=6) as file:
    file.write("service started\n")
    file.write("job completed\n")

Text modes create an io.TextIOWrapper. Specify the encoding instead of relying on the machine default. Use xt when an existing destination should make the operation fail.

Read line by line

import gzip

with gzip.open("events.log.gz", "rt", encoding="utf-8") as file:
    for number, line in enumerate(file, 1):
        process(number, line.rstrip())

Iteration avoids materializing the entire text. It complements the techniques in the giant-file guide. Applications should still limit line count and total expanded bytes.

Compress an existing file

import gzip
import shutil

with open("data.csv", "rb") as source:
    with gzip.open("data.csv.gz", "wb", compresslevel=6) as target:
        shutil.copyfileobj(source, target, length=1024 * 1024)

The transfer happens in chunks. For a production export, write to a temporary path, flush and close it, then rename it atomically so readers never see a partial file.

Use GzipFile with BytesIO

GzipFile accepts any binary file-like object, including an in-memory buffer:

import gzip
import io

buffer = io.BytesIO()
with gzip.GzipFile(fileobj=buffer, mode="wb", compresslevel=6, mtime=0) as gz:
    gz.write(b"content" * 1000)

payload = buffer.getvalue()

Closing GzipFile does not close the supplied fileobj. This lets code retrieve the buffer or append protocol data after the compressed member.

Header metadata

A GZIP header can include modification time and an original filename. When fileobj is supplied, the filename argument is used only for header metadata. Avoid leaking usernames, temporary paths, tenant names, or internal directory structures.

Concatenated members

gzip.decompress() supports multiple GZIP members concatenated into one byte string. Append mode also adds a new member to the end of a file. This is valid, but external tools may display or process members differently, so test every required consumer.

Handle invalid input

Malformed data can raise gzip.BadGzipFile, EOFError, or zlib.error.

import gzip
import zlib

try:
    with gzip.open("input.gz", "rb") as file:
        data = file.read()
except (gzip.BadGzipFile, EOFError, zlib.error) as exc:
    raise ValueError("invalid GZIP input") from exc

Log a safe identifier rather than raw content or sensitive paths.

Bound decompression

gzip.decompress() returns the full output and has no total-output parameter. Do not apply it blindly to large uploads. Read chunks through GzipFile and maintain a counter:

import gzip

maximum = 100 * 1024 * 1024
total = 0

with gzip.open("upload.gz", "rb") as file:
    while chunk := file.read(64 * 1024):
        total += len(chunk)
        if total > maximum:
            raise ValueError("expanded content exceeded the limit")
        consume(chunk)

Also limit compressed size, processing time, and member count. GZIP checks detect accidental corruption; they do not authenticate the source.

Compression levels

  • 0: store without compression.
  • 1: fastest, larger output.
  • 6: common balance and CLI default.
  • 9: slowest attempt at best compression.

Already-compressed images, video, and many PDF files typically gain little. Benchmark representative content instead of assuming level 9 is best.

GZIP is not a directory archive

GZIP represents a stream. To bundle filenames, permissions, and directories, create TAR first. ZIP combines container and compression; the practical differences are covered in the Python ZIP guide.

Command-line interface

Run python -m gzip to compress or decompress files. The CLI keeps input files and supports --fast, --best, and --decompress. The programmatic API is preferable when paths, errors, limits, and atomic replacement require strict control.

Testing strategy

Test empty input, Unicode encoded to bytes, truncated streams, concatenated members, several levels, deterministic headers, and output limits.

import gzip

def test_reproducible_gzip():
    first = gzip.compress(b"abc", mtime=0)
    second = gzip.compress(b"abc", mtime=0)
    assert first == second
    assert gzip.decompress(first) == b"abc"

Best practices

  • Use context managers.
  • Specify mode and encoding.
  • Set mtime=0 for reproducible artifacts.
  • Write output atomically.
  • Limit input, output, members, and CPU.
  • Keep sensitive names out of headers.
  • Test interoperability.
  • Do not confuse integrity checks with authentication.

Conclusion

Python gzip is a practical choice for widely compatible compressed streams. It supports memory operations, files, text, and arbitrary buffers, while Python 3.14 makes deterministic one-shot output the default.

Read the official gzip documentation and RFC 1952. To manage levels per environment, see Python configparser.

Share:

Facebook
WhatsApp
Twitter
LinkedIn

Article content

    Related articles

    Detailed shot of a Jungle Carpet Python (Morelia spilota cheynei) in its natural habitat.
    Advanced Python
    Foto de perfil de Leandro Hirt da Academify

    Python tarfile: Create Safe TARs

    Learn Python tarfile to create compressed TARs, inspect members, and extract archives with filters, limits, and path traversal protection.

    Ler mais

    Tempo de leitura: 4 minutos
    17/08/2026
    Neatly arranged blue office binders labeled with dates and names for organized storage.
    Advanced Python
    Foto de perfil de Leandro Hirt da Academify

    Python lzma: Compress XZ Files

    Learn Python lzma to create XZ files, process streams, select checks and filters, and enforce memory limits on external data.

    Ler mais

    Tempo de leitura: 4 minutos
    17/08/2026
    Detailed close-up texture of a snake's patterned skin showcasing natural patterns and scales.
    Advanced Python
    Foto de perfil de Leandro Hirt da Academify

    Python bz2: Compress with bzip2

    Learn Python bz2 to compress files and bytes, process data incrementally, handle concatenated streams, and limit external expansion.

    Ler mais

    Tempo de leitura: 4 minutos
    16/08/2026
    Close-up of a computer screen displaying colorful programming code with depth of field.
    Advanced Python
    Foto de perfil de Leandro Hirt da Academify

    Python zlib: Compress Data Safely

    Learn Python zlib to compress and decompress bytes, process streams, use checksums and dictionaries, and limit external data safely.

    Ler mais

    Tempo de leitura: 5 minutos
    16/08/2026
    File and system diagram representing INI configuration with Python configparser
    Advanced Python
    Foto de perfil de Leandro Hirt da Academify

    Python configparser: Read INI Files

    Learn Python configparser to read and write INI files, layer defaults, use interpolation and converters, and update files safely.

    Ler mais

    Tempo de leitura: 5 minutos
    16/08/2026
    RAM module representing object memory management with Python gc
    Advanced Python
    Foto de perfil de Leandro Hirt da Academify

    Python gc: Control Garbage Collection

    Learn Python gc to control cyclic collection, inspect tracked objects, diagnose memory growth, and observe collection pauses.

    Ler mais

    Tempo de leitura: 6 minutos
    16/08/2026