Compression in the Stack¶
Compression isn't only something you run by hand. It's configured throughout a typical Linux platform, and knowing where lets you tune it.
logrotate¶
/var/log/myapp/*.log {
daily
rotate 14
compress
delaycompress # leave the newest rotated file uncompressed
compresscmd /usr/bin/zstd
compressext .zst
compressoptions -T0 -10
uncompresscmd /usr/bin/unzstd
missingok
notifempty
}
delaycompress helps when the application may still write to the just-rotated file. The default compressor is gzip.
systemd-journald¶
Journal objects above a size threshold are compressed automatically (zstd on modern builds, previously xz or lz4). Controlled by Compress= in /etc/systemd/journald.conf (yes, no, or a byte threshold).
journalctl --disk-usage
HTTP¶
Servers compress responses on the fly with Content-Encoding: gzip, br (brotli), or zstd.
gzip on;
gzip_comp_level 5;
gzip_types text/plain text/css application/json application/javascript image/svg+xml;
gzip_min_length 1024;
gzip_static on; # serve pre-compressed .gz files if present
gzip_vary on;
Brotli and zstd need extra nginx modules. Pre-compressing static assets at build time (brotli -q 11, zopfli, zstd -19) gives the best ratio without per-request CPU. Avoid compressing secrets mixed with attacker-controlled content in the same response (the BREACH class of attacks).
Container images¶
OCI image layers are compressed tarballs. zstd layers pull and unpack noticeably faster than gzip:
podman push --compression-format zstd --compression-level 10 image registry/image:tag
docker buildx build --output type=image,name=registry/image:tag,compression=zstd,push=true .
Older container runtimes can't read zstd layers, so check your cluster's containerd or CRI-O version first. zstd:chunked (in podman/CRI-O) additionally allows partial pulls of changed files.
Databases¶
- PostgreSQL:
pg_dump -Fcwrites a compressed custom-format dump; PostgreSQL 16+ accepts-Z zstdand-Z lz4as well as gzip. Large column values are TOAST-compressed withpglzorlz4(default_toast_compression). WAL can be compressed withwal_compression. - MariaDB/MySQL: InnoDB page compression (
PAGE_COMPRESSED=1) and table compression; stream backups withmariadb-backup --stream=xbstream | zstd. - See pipelines for dump commands.
Elasticsearch and OpenSearch¶
index.codec: best_compressiontrades some CPU for noticeably smaller stored fields. It applies to newly written segments; force-merge to apply it to existing data.- Snapshot repositories compress metadata by default;
compress: trueon the repository extends this. - Transport and HTTP compression are separate settings.
Kernel and boot¶
The kernel image and initramfs can be compressed with gzip, xz, lz4, or zstd:
| System | Setting |
|---|---|
| dracut (Fedora, RHEL, Arch with dracut) | compress="zstd" in /etc/dracut.conf.d/*.conf |
| initramfs-tools (Debian, Ubuntu) | COMPRESS=zstd in /etc/initramfs-tools/initramfs.conf |
| mkinitcpio (Arch) | COMPRESSION="zstd" in /etc/mkinitcpio.conf |
Rebuild the initramfs afterwards. See cpio for inspecting images.
Memory: zram and zswap¶
- zram creates a compressed block device in RAM, usually used as swap. It's the default on Fedora and common on low-memory nodes.
- zswap is a compressed cache in front of a regular swap device.
zramctl # devices, algorithm, ratio
cat /sys/block/zram0/comp_algorithm # [lzo-rle] lz4 zstd ...
cat /sys/module/zswap/parameters/compressor
Filesystems¶
Btrfs, ZFS and others can compress transparently. See SquashFS and compressed filesystems.
Packages¶
| Distro | Package payload compression |
|---|---|
| Arch | zstd |
| Fedora / RHEL 9+ | zstd (RPM payload) |
| Debian / Ubuntu | xz historically; zstd on newer Ubuntu releases |
| Alpine | gzip |
See ar.