Kompression im Backup: Was sich wie stark komprimieren lässt – ein Praxistest mit lionbackup
Veröffentlicht am 5. November 2026 · Praxistest · ← Blog
Wie viel kleiner wird ein Backup durch Kompression? Zwischen gar nicht und einem Faktor 16, und das hängt fast nur von den Daten ab. Wir haben 55 Dateien mit zusammen rund 3,8 GB aus allen Bereichen eines Firmenbackups mit zwölf Verfahren und Stufen gemessen: Logs, Datenbanken, Office-Dokumente, Fotos, Audio und Video, VM-Images, Archive, verschlüsselte Daten und den Silesia-Referenzkorpus. Eine Gegenprobe mit dem lionbackup-Client zeigt, was davon im Backup ankommt.
Was Kompression eigentlich ist
Kompression ist Umkodierung: Dieselbe Information wird mit weniger Bits dargestellt, weil die ursprüngliche Darstellung Redundanz enthält. Ein Backup darf dabei nur verlustfrei arbeiten. Nach der Dekompression muss jedes Byte exakt dem Original entsprechen, sonst ist eine Datenbankdatei oder ein Disk-Image unbrauchbar.
Verlustbehaftete Verfahren wie JPEG, MP3 oder H.264 werfen dagegen gezielt Information weg, die ein Mensch kaum wahrnimmt. Sie erreichen Faktoren von 10 bis 100, kommen für ein Backup aber nicht in Frage. Der Artikel behandelt deshalb nur verlustfreie Verfahren. Genau diese Unterscheidung erklärt später, warum ein JPEG im Backup nicht mehr schrumpft.
Vier Arten von Redundanz
Jedes Kompressionsverfahren ist auf bestimmte Formen von Redundanz spezialisiert:
- Wiederholung: Dieselbe Zeichenfolge kommt mehrfach vor. In einem SQL-Dump steht
INSERT INTO kunden VALUES (tausendfach, in einem Logfile wiederholt sich der Hostname in jeder Zeile. - Ungleiche Häufigkeit: Manche Bytes sind viel häufiger als andere. In deutschem Text macht das
eetwa 17 Prozent aller Buchstaben aus, dasqunter 0,1 Prozent. Trotzdem belegen beide 8 Bit. - Kontext: Das nächste Zeichen ist aus den vorherigen oft vorhersagbar. Nach
qfolgt fast immeru, nach2026-11-0eine Ziffer. - Struktur: Dateiformate enthalten Füllbytes, Ausrichtung auf Blockgrenzen, leere Tabellenzellen oder ungenutzte Sektoren in Disk-Images, oft lange Nullfolgen.
Die Entropie als untere Grenze
Claude Shannon hat 1948 bewiesen, dass es für jede Datenquelle eine untere Grenze gibt, unter die kein verlustfreier Kodierer kommt. Diese Grenze ist die Entropie der Quelle, gemessen in Bit pro Symbol:
Dabei ist p(x) die Wahrscheinlichkeit des Symbols x. Ein Byte, dessen 256 Werte alle gleich wahrscheinlich sind, hat die Entropie 8 Bit und lässt sich nicht verkürzen. Ein Byte, das zu 99 Prozent den Wert 0 und sonst den Wert 1 hat, trägt nur etwa 0,08 Bit Information und lässt sich im Mittel auf ein Hundertstel kodieren.
Das erklärt die beiden Extremfälle im Test: Eine Datei aus lauter Nullbytes schrumpft auf wenige Kilobyte, weil ihre Entropie praktisch null ist. Eine Datei aus Zufallsbytes bleibt gleich groß oder wird minimal größer, weil ihre Entropie bereits bei 8 Bit pro Byte liegt. Für englischen Text liegt die Entropie nach Shannons Schätzungen und späteren Experimenten bei etwa 1 bis 1,5 Bit pro Zeichen, obwohl ASCII 8 Bit verwendet. Theoretisch wäre also ein Faktor 5 bis 8 drin; für englische Prosa erreichten zstd -3 bis xz -6 im Test 2,8 bis 3,6.
Warum kein Verfahren alles komprimieren kann
Ein Abzählargument zeigt die Grenze: Es gibt 2n verschiedene Dateien mit n Bit, aber nur 2n − 1 Dateien mit weniger als n Bit. Ein Kompressor, der jede Datei verkleinert, müsste zwei verschiedene Eingaben auf dieselbe Ausgabe abbilden, und dann wäre die Dekompression mehrdeutig. Jedes Verfahren, das manche Daten verkleinert, muss andere vergrößern. In der Praxis sind das bereits komprimierte oder verschlüsselte Daten; dort erzeugten die Verfahren im Test einen Overhead von 0,002 bis 0,45 Prozent.
Modell und Kodierer
Jeder praktische Kompressor besteht aus zwei Teilen. Das Modell findet Redundanz: Es sucht Wiederholungen, zählt Häufigkeiten oder schätzt aus dem Kontext, welches Zeichen als nächstes kommt. Der Kodierer übersetzt die Ausgabe des Modells in möglichst kurze Bitfolgen, sodass häufige Ereignisse weniger Bits bekommen als seltene.
Die Qualität des Modells entscheidet, wie nahe man der Entropie kommt, seine Geschwindigkeit, wie viele Megabyte pro Sekunde durch den Kompressor laufen. Dieses Spannungsfeld unterscheidet die Verfahren im Test: LZ4 verwendet ein sehr einfaches Modell und schafft knapp 500 MB/s auf einem Kern, xz verwendet ein aufwendiges Modell und kommt bei maximaler Stufe auf unter 2 MB/s.
So wird gemessen
Die Kompressionsrate ist im ganzen Artikel das Verhältnis der unkomprimierten zur komprimierten Größe. Eine Rate von 4,0 bedeutet, dass 400 MB auf 100 MB geschrumpft sind, also 75 Prozent Ersparnis. Der Durchsatz ist die unkomprimierte Datenmenge, die pro Sekunde verarbeitet wird, getrennt für Kompression und Dekompression.
Wie die Verfahren im Inneren arbeiten
Alle Kompressoren im Test kombinieren zwei bis drei Grundbausteine: ein Verfahren zum Finden von Wiederholungen, ein Verfahren zum sparsamen Kodieren der Ergebnisse und manchmal eine Vorsortierung der Daten. Die Bausteine stammen aus den Jahren 1952 bis 2013; ihre Kombination entscheidet über Rate und Tempo.
Lauflängenkodierung: der Urahn
Die einfachste Form ersetzt eine Folge gleicher Bytes durch Zähler und Wert. Aus AAAAAAAB wird 7A1B, aus einem Megabyte Nullen werden wenige Bytes. Lauflängenkodierung (RLE) steckt in Fax-Übertragungen, in BMP- und PCX-Bildern und als Vorstufe in bzip2. Bei Text, Code oder Datenbanken versagt sie, weil dort kaum lange gleiche Folgen vorkommen.
LZ77: das gleitende Fenster
Abraham Lempel und Jacob Ziv veröffentlichten 1977 die Idee, die bis heute den meisten Allzweckkompressoren zugrunde liegt. Der Kodierer merkt sich die zuletzt gesehenen Bytes in einem Fenster. Taucht eine Byte-Folge auf, die im Fenster bereits vorkam, schreibt er statt der Bytes nur ein Paar aus Abstand und Länge.
Aus lionbackup komprimiert, lionbackup verschlüsselt wird so lionbackup komprimiert, (24,11)verschlüsselt: Gehe 24 Bytes zurück und kopiere 11 Bytes. Ein Verweis kostet wenige Bytes, egal ob er 4 oder 258 Bytes ersetzt. Je länger und häufiger die Wiederholungen, desto stärker die Kompression.
Die Fenstergröße entscheidet, wie weit entfernt eine Wiederholung liegen darf. Deflate (gzip, ZIP, PNG) hat ein Fenster von 32 KiB. Zstandard arbeitet je nach Stufe mit 512 KiB bis 8 MiB und mit --long mit 128 MiB und mehr. LZMA (xz) nutzt bei Stufe 6 ein Wörterbuch von 8 MiB, bei Stufe 9 von 64 MiB. Zwei Kopien derselben 20-MB-Datei in einem Archiv erkennt gzip deshalb nicht, xz -9 und zstd --long dagegen schon. Der Test misst diesen Effekt später direkt.
Das Suchen der Wiederholungen ist der teuerste Schritt. Schnelle Stufen (zstd -1, gzip -1, LZ4) prüfen pro Position nur wenige Kandidaten. Hohe Stufen (zstd -19, xz -9) verfolgen Hash-Ketten oder Binärbäume über hunderte Kandidaten und berechnen per optimalem Parsing, welche Kombination aus Verweisen und Literalen insgesamt am wenigsten Bits kostet. Deshalb wird zstd von Stufe 3 auf Stufe 19 über hundertmal langsamer beim Komprimieren, beim Dekomprimieren aber kaum: Der Dekoder kopiert nur Bytes, suchen muss er nie.
LZ78 und das daraus abgeleitete LZW (1984) arbeiten mit einem explizit aufgebauten Wörterbuch. LZW steckt in GIF und älteren TIFF- und PDF-Dateien, spielt für moderne Backups aber keine Rolle mehr.
Huffman-Kodierung: kurze Codes für häufige Zeichen
David Huffman entwickelte 1952 ein Verfahren, das jedem Symbol einen Code variabler Länge zuweist: häufige Symbole bekommen kurze Codes, seltene lange. Die Codes entstehen über einen Binärbaum, in dem die beiden seltensten Symbole wiederholt zu einem Knoten verschmolzen werden. Kein Code ist Präfix eines anderen, deshalb lässt sich der Bitstrom ohne Trennzeichen eindeutig dekodieren.
Vier Symbole mit den Häufigkeiten e: 50 Prozent, n: 25 Prozent, a und q: je 12,5 Prozent ergeben die Codes 0, 10, 110 und 111. Statt 8 Bit pro Zeichen braucht der Text im Mittel 1,75 Bit. Deflate teilt den Datenstrom in Blöcke und baut für jeden Block eigene Huffman-Tabellen, die komprimiert im Datenstrom stehen.
Huffman hat eine bekannte Schwäche: Codelängen sind ganze Zahlen. Ein Symbol mit 90 Prozent Wahrscheinlichkeit trägt nur 0,15 Bit Information, bekommt aber mindestens ein ganzes Bit. Bei stark ungleichen Verteilungen verschenkt Huffman deshalb bis zu einem Bit pro Symbol.
Arithmetische Kodierung und ANS: Bruchteile von Bits
Arithmetische Kodierung (ab 1976, praktisch ab den 1980ern) löst dieses Problem. Sie kodiert die gesamte Nachricht als eine Zahl in einem Intervall zwischen 0 und 1, das mit jedem Symbol proportional zu dessen Wahrscheinlichkeit schrumpft. Ein Symbol mit 90 Prozent kostet dann tatsächlich nur 0,15 Bit. LZMA (xz, 7-Zip) verwendet eine Variante namens Range-Coder, die die Wahrscheinlichkeiten laufend aus dem Kontext lernt: Ob nach einem Verweis ein Literal oder ein weiterer Verweis folgt, schätzt sie aus den vorherigen Entscheidungen.
Der Preis ist Rechenzeit, weil pro Symbol Multiplikationen und Divisionen anfallen. Jarek Duda beschrieb ab 2009 mit Asymmetric Numeral Systems (ANS) einen Weg, dieselbe Effizienz mit Tabellenzugriffen zu erreichen; die schnellen Varianten folgten 2013. Zstandard kodiert Längen und Abstände mit der tabellenbasierten ANS-Variante Finite State Entropy (FSE) und Literale mit Huffman. Das ist ein Grund, warum zstd im Test bei gleicher Rate fast sechsmal so schnell dekomprimierte wie gzip.
Burrows-Wheeler-Transformation: erst sortieren, dann kodieren
bzip2 (1996) geht einen anderen Weg. Es sortiert alle zyklischen Rotationen eines Blocks von bis zu 900 KB alphabetisch und behält nur die letzte Spalte. Die Transformation ist umkehrbar und komprimiert selbst nichts, aber sie gruppiert Bytes mit gleichem Kontext: Alle Zeichen, die vor einem ackup stehen, landen nebeneinander, und das ist fast immer ein b.
Danach folgen eine Move-to-Front-Transformation, Lauflängenkodierung und Huffman. Für Text liefert das bessere Raten als Deflate. Nachteile sind die Blockgrenze, hinter der keine Wiederholung erkannt wird, und die langsame Dekompression: Die Rücktransformation springt kreuz und quer durch den Block und wartet ständig auf den Arbeitsspeicher.
Kontextmodelle: die Spitze der Rate
Verfahren wie PAQ, zpaq oder cmix sagen für jedes Bit aus den vorangegangenen Bytes eine Wahrscheinlichkeit voraus, mit dutzenden Modellen, die ein neuronaler Mischer gewichtet. Sie erreichen die besten Raten überhaupt, komprimieren aber mit weit unter 2 MB/s und brauchen Gigabytes an Speicher. Für Backups im Terabyte-Bereich sind sie nicht praktikabel; der Test lässt sie außen vor.
Die Verfahren im Test
| Verfahren | Jahr | Bausteine | Fenster | Typischer Einsatz | Im lionbackup-Client |
|---|---|---|---|---|---|
| LZ4 | 2011 | LZ77 ohne Entropiekodierung | 64 KiB | ZFS, Kernel, Datenbanken | nein |
| Deflate (gzip) | 1992 | LZ77 + Huffman | 32 KiB | ZIP, PNG, HTTP, tar.gz, Container-Layer | GZIP |
| Zstandard (zstd) | 2015 | LZ77 + FSE/Huffman | 512 KiB bis 128 MiB | Backups, Pakete (Fedora, Arch), btrfs, Kernel | ZSTD (empfohlen) |
| Brotli | 2015 | LZ77 + Huffman + Kontext + 120-KB-Wörterbuch | bis 16 MiB | Web-Auslieferung (HTTP) | nein |
| bzip2 | 1996 | BWT + MTF + RLE + Huffman | 900-KB-Block | Quellcode-Archive, ältere Backups | nein |
| LZMA2 (xz) | 1998/2009 | LZ77 + Range-Coder mit Kontext, optimales Parsing | 1 MiB bis 1,5 GiB | Linux-Pakete, Firmware, Archive mit maximaler Rate | LZMA2 bzw. XZ |
LZ4, Brotli und bzip2 laufen als Vergleichspunkte mit, um die Spannweite zwischen maximalem Tempo und maximaler Rate zu zeigen. Wichtig für das Lesen der Ergebnisse: Gemessen wurden die Referenzwerkzeuge auf der Kommandozeile. Der Client verwendet für dieselben Formate eigene Go-Bibliotheken mit anderen Stufen; was das ändert, zeigt die Gegenprobe.
Was alle Verfahren gemeinsam haben
Ein Kompressor sieht nur Bytes, keine Dateitypen. Er weiß nicht, ob er ein JPEG, eine Datenbank oder ein Disk-Image vor sich hat. Er findet Wiederholungen und schiefe Häufigkeiten, wo sie existieren, und scheitert, wo ein anderes Verfahren sie bereits entfernt hat. Deshalb liegen die Ergebnisse im Test zwischen einer Rate von 1,00 und über einer Million.
Wie der lionbackup-Client komprimiert
Der Client ist ein einzelnes Go-Programm, das den lokalen Teil eines Backup-Laufs übernimmt: Quellen lesen, komprimieren, verschlüsseln und hochladen. Die Reihenfolge ist zwingend. Verschlüsselte Daten sehen für jeden Kompressor wie Zufall aus; komprimiert werden kann nur vorher.
Die Verarbeitungskette
- Quellen lesen. Jeder Eintrag unter
files:wird zu einem eigenen Archiv: Der Client verpackt die Quelle in einen tar-Strom. Lesefehler unterhalb einer Quelle führen je nachon_read_errorzu Warnung und Überspringen oder zum Abbruch. - Komprimieren. Der tar-Strom läuft durch das in
compression_methodgewählte Verfahren mit der Stufe auscompression_level. Weil jede Quelle ihr eigenes Archiv bekommt, findet die Kompression Wiederholungen nur innerhalb einer Quelle. - Verschlüsseln. Verschlüsselt wird immer. Der Client erzeugt pro Archiv einen zufälligen 32-Byte-Datenschlüssel (DEK) und verschlüsselt nur diesen asymmetrisch für den Empfängerschlüssel. Die Nutzdaten laufen symmetrisch in 64-KiB-Blöcken durch XChaCha20-Poly1305.
- Übertragen. Die fertige
.lbk-Datei geht in Teilstücken an einen Citadel der gewählten Storage-Zone. Die Liste der Citadels kommt aus einem DNS-TXT-Record, wird zufällig gemischt und per/v1/healthgeprüft; fällt ein Server aus, wechselt der Client auf den nächsten. Während eine Datei übertragen wird, packt der Client bereits die nächste (Fließbetrieb). Die Replikation über mehrere Standorte erfolgt serverseitig.
Verfahren, Stufen und Fenster im Client
Zwei Einstellungen steuern die Kompression. compression_method wählt das Verfahren: ZSTD, GZIP oder LZMA2 (auch XZ). Fehlt der Eintrag, nimmt der Client GZIP; die Beispielkonfiguration und die Dokumentation empfehlen ZSTD. compression_level wählt die Stufe von 1 bis 9, Standard ist 5; 0 schaltet die Kompression ab, verschlüsselt wird trotzdem.
Die drei Verfahren setzen die Stufe unterschiedlich um:
compression_level |
ZSTD | GZIP | LZMA2 |
|---|---|---|---|
| 0 | aus | aus | aus |
| 1 | schnellste Stufe, etwa zstd -1, Fenster 4 MiB | Stufe 1 | immer gleich: Wörterbuch 8 MiB, ein Kern |
| 2 bis 5 | Standardstufe, etwa zstd -3, Fenster 8 MiB | Stufe 2 bis 5 | wie oben |
| 6 bis 8 | etwa zstd -7 bis -8, Fenster 8 MiB | Stufe 6 bis 8 | wie oben |
| 9 | stärkste Stufe der Bibliothek, Fenster 8 MiB | Stufe 9 | wie oben |
Die Werte stammen aus dem Quelltext des Clients und seiner Bibliotheken: klauspost/compress für ZSTD, klauspost/pgzip für GZIP und ulikunitz/xz für LZMA2. Drei Folgen sind für die Messergebnisse wichtig:
- ZSTD im Client entspricht zstd -1 bis etwa -11, nicht zstd -19. Die Ultra-Stufen der Kommandozeile gibt es im Client nicht.
- Das Fenster ist fest. GZIP sieht 32 KiB zurück, ZSTD 8 MiB (auf Stufe 1: 4 MiB) und LZMA2 8 MiB. Wiederholungen, die weiter auseinanderliegen oder in verschiedenen Quellen stehen, speichert der Client mehrfach; einen Modus wie
zstd --longbietet er nicht. - GZIP nutzt alle Kerne, ZSTD und LZMA2 im Wesentlichen einen. pgzip komprimiert Blöcke von 1 MiB parallel. Die ZSTD-Bibliothek arbeitet in der Einstellung des Clients mit einem Kern und einem Hilfsfaden, LZMA2 mit einem Kern. Beim Entpacken ist ZSTD trotzdem mit Abstand am schnellsten.
Beim Restore erkennt der Client das Verfahren an den ersten Bytes der entschlüsselten Daten (1f 8b für gzip, 28 b5 2f fd für zstd, fd 37 7a 58 5a 00 für xz, sonst ein unkomprimiertes tar).
Das .lbk-Dateiformat
"LIONBKP1" | Version | Header-Länge | age-verschlüsselter Header <- asymmetrisch (KEM)
Header-Inhalt: 32-Byte-DEK | JSON-Metadaten
Chunk 0 | Chunk 1 | ... | Chunk N (isLast) <- symmetrisch (DEM)
Chunk = [Länge | 24-Byte-Nonce | Chiffretext + 16-Byte-Tag]Den Header verschlüsselt age; neue Schlüssel des Clients sind ein Hybrid aus ML-KEM-768 und X25519 und damit gegen Angriffe mit Quantencomputern ausgelegt. Jeder Chunk trägt als zusätzlich authentifizierte Daten seinen Index und ein Ende-Flag. Umsortierte Chunks fallen deshalb bei der Entschlüsselung auf, eine abgeschnittene Datei am fehlenden letzten Chunk.
Was Kompression für den Backup-Lauf bedeutet
Die Kompressionsrate wirkt an drei Stellen. Sie bestimmt das Volumen, das über die Leitung geht, und damit die Laufzeit bei begrenzter Bandbreite. Sie bestimmt den belegten Speicher in der Storage-Zone und damit die laufenden Kosten. Und das Verfahren bestimmt, wie lange die CPU des Quellsystems belegt ist.
Bei 100 Mbit/s Upload überträgt die Leitung etwa 12 MB/s. Ein Kompressor, der mit 200 MB/s eine Rate von 2,5 erreicht, macht daraus effektiv 30 MB/s Nutzdaten, ohne selbst zum Engpass zu werden. Ein Kompressor mit 4 MB/s und Rate 3,2 wird dagegen selbst zum Engpass: Das Backup dauert siebeneinhalbmal so lange wie mit dem schnelleren Verfahren, obwohl weniger Bytes übertragen werden.
Selbst messen mit --autotune
Der Client bringt den Vergleich für die eigenen Daten mit: lionbackup-client --autotune komprimiert jede Quelle einmal mit ZSTD, GZIP und LZMA2 auf der eingestellten Stufe, ohne zu verschlüsseln oder hochzuladen. Die Tabelle zeigt Ausgabegröße, die Größe in Prozent des Originals (25 Prozent entsprechen einer Rate von 4,0), Laufzeit und Durchsatz. Als Empfehlung nennt der Client das Verfahren mit dem kleinsten Produkt aus Größe und Laufzeit. Wie das aussieht und warum die Empfehlung nicht immer ZSTD lautet, zeigt die Gegenprobe weiter unten.
Testaufbau und Methodik
Der Haupttest misst 55 Dateien mit zusammen rund 3,8 GB gegen zwölf Verfahren und Stufen, insgesamt 625 Einzelmessungen. Dazu kommen ein Stufen-Sweep mit 51 Konfigurationen, ein Fenster-Experiment mit 70 und ein Versions-Experiment mit 14 Messungen. Für die Kompressionsrate spielt die Dateigröße ab einigen Megabyte kaum noch eine Rolle; 3,8 GB reichen deshalb aus.
Hardware und Software
Die Messungen liefen auf einem einzelnen Kern eines Intel Xeon mit 2,1 GHz unter Ubuntu 24.04 mit 3,9 GB RAM, mit den Referenzwerkzeugen in der jeweils paketierten Version: gzip 1.12, bzip2 1.0.8, xz 5.4.5, zstd 1.5.5, lz4 1.9.4 und brotli 1.1.0. Jede Datei wurde vor der Messung einmal gelesen, damit sie im Seitencache liegt und die Messung nicht die Festplatte misst. Die Zeit ist die Wanduhrzeit um den Prozess, der Speicherbedarf die maximale Resident Set Size.
Ein Kern ist bewusst gewählt: So vergleicht der Test die Verfahren selbst und nicht, wie gut ein Werkzeug parallelisiert. Wie sich der Client auf einem Rechner mit mehreren Kernen verhält, zeigt die Gegenprobe.
Die Testdaten
Die Dateien stammen aus drei Quellen. Erstens der Silesia-Korpus, ein seit 2003 etablierter Referenzdatensatz aus zwölf realen Dateien, den auch die Entwickler von zstd und lz4 für ihre Benchmarks verwenden: englische Literatur (dickens), Programmdateien von Mozilla 1.0 (mozilla), ein MRT-Bild (mr), eine Chemie-Datenbank (nci), eine Windows-DLL (ooffice), eine MySQL-Datenbank (osdb), ein PDF (reymont), der Samba-Quellcode (samba), ein Sternkatalog (sao), ein HTML-Wörterbuch (webster), ein Röntgenbild (x-ray) und XML-Dateien (xml).
Zweitens reale Dateien aus dem Testsystem: 300 Linux-Bibliotheken und Programme, der Python-Quellcode der Standardbibliothek, der Go-Quellcode von klauspost/compress (die zstd-Implementierung des lionbackup-Clients), deren Git-Objekte und 200 TrueType-Schriften.
Drittens synthetische Dateien, deterministisch mit festem Zufalls-Seed erzeugt, damit der Test reproduzierbar bleibt: Syslog- und Nginx-Logs mit realistischen Zeitstempeln, IP-Adressen und Meldungen; ein MySQL-Dump, CSV, JSON Lines, XML, SQLite und Excel aus denselben 220.000 Bestelldatensätzen; Word-, PowerPoint- und PDF-Dokumente; HTML-Seiten; eine Mailbox mit Base64-Anhängen; 24 Fotos mit Sensorrauschen als JPEG, PNG, BMP und TIFF; dreiminütige Audiodaten als WAV, FLAC und MP3; ein H.264-Video; Messreihen als float64 und gerundet als float32; ein ext4-Disk-Image mit einem Linux-Teilsystem als raw, qcow2, VMDK, VDI und ISO; tar, tar.gz und ZIP desselben Baums; eine AES-verschlüsselte Datei, Zufallsdaten und Nullbytes.
Die synthetischen Geschäftsdaten verwenden ein begrenztes Vokabular aus 40 Vornamen, 40 Nachnamen, 30 Städten und 20 Produkten. Sie komprimieren deshalb etwas besser als echte Kundendaten. Wo es reale Vergleichsdaten gibt, etwa bei Datenbanken (synthetischer Dump gegen Silesia osdb) oder Quellcode, liegen die Ergebnisse nahe beieinander. Die Werte für HTML und die Mailbox sind als Obergrenze zu lesen; echte Logs können dagegen noch gleichförmiger sein als die synthetischen.
Die Verfahren und Stufen
| Konfiguration | Rolle im Test | Entspricht im Client |
|---|---|---|
| lz4 -1 | Untergrenze der Rate, Obergrenze des Tempos | – |
| gzip -1, gzip -6 | schnellste und Standardstufe von gzip | ungefähr GZIP, Stufe 1 und 6 |
| zstd -1, -3, -9, -19 | von der schnellsten bis zur starken Stufe | ZSTD 1, 2 bis 5 und etwa 9; zstd -19 nicht erreichbar |
| xz -1, -6, -9 | schnellste, Standard- und Maximalstufe | LZMA2 hat das Wörterbuch von xz -6, erreicht aber weniger Rate |
| bzip2 -9 | Klassiker mit Burrows-Wheeler-Transformation | – |
| brotli -6 | Googles Web-Kompressor mit eingebautem Wörterbuch | – |
Für den Stufen-Sweep liefen zusätzlich zstd 1 bis 22, gzip 1 bis 9, xz 0 bis 9, bzip2 1/5/9, lz4 1/3/9/12 und brotli 1/5/9/11 auf einem 64-MB-Ausschnitt eines Server-Backups aus Logs, SQL-Dump, PDF, Quellcode, Binaries, Fotos, Office-Dokumenten und JSON.
Die Kennzahlen pro Verfahren sind über ein Kernset von 45 Dateien berechnet, ohne die drei Extremfälle (Nullbytes, Zufall, verschlüsselt) und ohne die Dateien, für die nicht alle Konfigurationen gemessen wurden. Als Mittelwert der Rate dient das geometrische Mittel, weil Raten multiplikativ sind: Ein Verfahren, das eine Datei auf die Hälfte und eine andere auf ein Viertel bringt, hat im Mittel eine Rate von 2,83 und nicht von 3,0. Der Durchsatz ist Gesamtmenge geteilt durch Gesamtzeit; große Dateien zählen dadurch stärker.
Ergebnisse nach Dateiformat
Zwischen einer Rate von 1,00 für JPEG, MP3 und verschlüsselte Daten und 15,9 für XML liegt der Faktor 16; die Nullbytes-Datei sprengt mit über einer Million jede Skala. Innerhalb eines Formats liegen die Verfahren dagegen meist nur 20 bis 60 Prozent auseinander. Die Datenart entscheidet über die Größenordnung, das Verfahren über den Feinschliff.
Die Rangfolge der Datenarten
Aus den geometrischen Mitteln pro Kategorie ergibt sich eine Rangfolge, die sich zwischen den Verfahren nur wenig verschiebt (sortiert nach zstd -3):
| Datenart | zstd -3 | zstd -19 | xz -6 | Charakter |
|---|---|---|---|---|
| Logdateien | 6,0 | 8,4 | 8,5 | Zeilenweise Wiederholung von Hostnamen, Pfaden, Meldungen |
| CSV, JSON, XML | 5,7 | 8,6 | 8,9 | Feldnamen und Trennzeichen in jedem Datensatz |
| Quellcode | 5,7 | 7,7 | 7,9 | Schlüsselwörter, Einrückung, Bezeichner |
| Datenbanken | 3,5 | 5,0 | 5,4 | Spaltenwerte wiederholen sich, aber binäre Seitenstruktur |
| HTML | 3,5 | 6,7 | 6,8 | Tags und Vorlagen, dazwischen Text |
| Silesia (gemischt, real) | 3,2 | 4,1 | 4,3 | Realistischer Querschnitt |
| VM-Images und ISO | 2,9 | 3,7* | 3,6 | Mischung aus Binaries, Text und Leerbereichen |
| Mailbox | 1,65 | 2,7 | 2,75 | Text komprimiert, Base64-Anhänge kaum |
| Binaries, Schriften, Git | 1,6 | 1,9 | 2,0 | Maschinencode 2,4 bis 3,3, Git-Objekte 1,0 |
| Messdaten | 1,5 | 1,8 | 2,1 | float64 1,1 bis 1,3, gerundet 2,2 bis 3,3 |
| Office-Dateien | 1,35 | 1,5 | 1,6 | .xls 3,3 bis 5,7, .docx/.xlsx/.pptx 1,0 |
| 1,3 | 1,3 | 1,3 | Streams intern bereits Deflate-komprimiert | |
| Bilder | 1,02 | 1,05 | 1,14 | JPEG und PNG 1,00, BMP/TIFF mit Rauschen 1,04 bis 1,29 |
| Audio und Video | 1,01 | 1,02 | 1,04 | MP3, MP4, FLAC 1,00, WAV 1,06 bis 1,15 |
* Für zstd -19 liegen bei den VM-Images nur zwei der sechs Dateien vor; der Wert 3,7 gilt für das unkomprimierte qcow2.
Text und Logs: der Idealfall
Logdateien sind der Idealfall für LZ77. In jeder Zeile wiederholen sich Datum, Hostname, Prozessname und große Teile der Meldung; nur Zeitstempel, PIDs und IP-Adressen wechseln. Das Nginx-Access-Log erreicht mit zstd -3 eine Rate von 6,9 bei 245 MB/s, mit zstd -19 10,0 und mit bzip2 sogar 13,0. Das Syslog liegt mit 5,3 bis 8,3 darunter, weil die Meldungstexte vielfältiger sind.
Bei beiden Logs liegt gzip -6 in der Rate vor zstd -3 (7,9 gegen 6,9 und 5,7 gegen 5,3), und zstd -1 vor zstd -3. Die schnellen Stufen verwenden eine Suchstrategie, die bei extrem gleichförmigen Zeilen zufällig besser greift; ab zstd -9 liegt zstd wieder klar vorn. Echte Systemprotokolle sind oft noch gleichförmiger als die synthetischen: In der Gegenprobe erreichte ein Systemprotokoll im Client Raten über 15.
Strukturierte Daten liegen noch höher. Derselbe Datensatz mit 220.000 Bestellungen erreicht als XML eine Rate von 8,3 (zstd -3) bis 15,9 (bzip2), als JSON Lines 6,2 bis 11,8 und als CSV 3,5 bis 5,8. XML wiederholt in jedem Datensatz vierzehn Tag-Paare, JSON vierzehn Schlüssel, CSV nur dreizehn Semikolons. Je geschwätziger das Format, desto höher die Rate, aber die Größe nach der Kompression ist fast gleich: XML schrumpft mit zstd -3 von 91 auf 11 MB, JSON von 66 auf 11 MB, CSV von 31 auf 9 MB. Die Struktur ist nach der Kompression fast umsonst, die Nutzdaten kosten.
Quellcode liegt in derselben Klasse. Der Python-Quellcode erreicht 4,7 (zstd -3) bis 6,7 (xz -6), der Go-Code 6,9 bis 9,4, der C-Code von Samba aus dem Silesia-Korpus 4,3 bis 5,7. Englische Prosa (dickens) kommt auf 2,8 bis 3,6, ein Wörterbuch in HTML (webster) auf 3,4 bis 4,8. Natürliche Sprache komprimiert schlechter als Code, weil der Wortschatz größer und Wiederholungen seltener sind.
Datenbanken: Dump gegen Datei
Derselbe Datenbestand verhält sich als SQL-Dump und als SQLite-Datei unterschiedlich. Der Dump erreicht 3,9 (zstd -3) bis 6,7 (bzip2), die SQLite-Datei 3,2 bis 4,8. Der Dump ist reiner Text mit tausendfach wiederholten INSERT-Präfixen; die Datenbankdatei enthält binäre Seitenköpfe, Indexstrukturen und Verwaltungsdaten mit hoher Entropie. Die MySQL-Datenbank osdb aus dem Silesia-Korpus liegt mit 2,9 bis 3,6 im selben Bereich wie die SQLite-Datei und bestätigt das mit realen Daten.
Für Backups heißt das: Ein logischer Dump ist nicht nur portabler, sondern auch kompakter. Im Test war er schon unkomprimiert kleiner (36 gegen 42 MB), nach zstd -3 belegte er 9 MB statt 13 MB.
Office-Dokumente: eine Frage des Jahrgangs
Die alte Excel-Datei im BIFF-Format (.xls) komprimiert mit 3,3 bis 5,7 gut, weil das Format Zellen unkomprimiert als binäre Datensätze speichert. Dieselben Daten als .xlsx erreichen 1,00 bis 1,04: Seit 2007 sind Office-Dateien ZIP-Container, deren XML-Inhalt bereits mit Deflate komprimiert ist. Word- und PowerPoint-Dateien zeigen dasselbe Bild.
Eine Ausnahme fällt auf: Das Archiv aus zwölf Word-Dateien erreicht mit xz -9 eine Rate von 2,93, mit zstd -19 und xz -6 immerhin 1,17. Die Dokumente enthalten dieselben eingebetteten Fotos, und Verfahren mit großem Fenster erkennen die zweite und dritte Kopie eines Bildes über Dateigrenzen hinweg. Firmenlogos, Vorlagenbilder und Diagramme wiederholen sich in echten Dokumentbeständen ständig; die Fenstergröße entscheidet, ob das Backup davon profitiert.
PDF liegt bei 1,2 bis 1,4, unabhängig von Verfahren und Stufe. Das Text-PDF hat intern Flate-komprimierte Inhaltsströme, das Scan-PDF enthält JPEG-Seiten; beide lassen nur Objektstrukturen, Querverweistabellen und Schriften übrig.
Bilder, Audio, Video: fertig komprimiert
JPEG-Fotos erreichen exakt 1,00, mit bzip2 1,02. PNG ebenfalls 1,00, weil PNG intern Deflate verwendet; selbst xz findet in einem Deflate-Strom nichts mehr. Dieselben Fotos als unkomprimiertes BMP oder TIFF kommen nur auf 1,04 bis 1,29. Die Testfotos enthalten Sensorrauschen, und Rauschen ist per Definition nicht vorhersagbar. Ein unkomprimiertes Format heißt nicht, dass die Daten komprimierbar sind.
Spezialisierte Bildkompression schlägt hier jeden Allzweckkompressor: PNG brachte dieselben Fotos von 84 auf 47 MB (Rate 1,8), weil es jedes Pixel aus seinen Nachbarn vorhersagt und nur die Abweichung speichert; xz kam auf 1,29. Das Röntgenbild x-ray (1,4 bis 2,1) und das MRT-Bild mr (2,7 bis 4,1) aus dem Silesia-Korpus zeigen die Bandbreite realer medizinischer Rohbilder.
Audio verhält sich ebenso: WAV erreicht 1,06 bis 1,15, FLAC und MP3 exakt 1,00. FLAC ist bereits eine spezialisierte verlustfreie Kompression, die Abtastwerte linear vorhersagt und das WAV auf 63 Prozent bringt. MP4-Video liegt bei 1,00 bis 1,02.
Messdaten: der unterschätzte Fall
Drei Messreihen mit je fünf Millionen Werten als float64 erreichen nur 1,09 (zstd -3) bis 1,30 (xz -6), obwohl die Werte glatte Kurven mit leichtem Rauschen sind. Das Problem ist die Darstellung: Die 52-Bit-Mantisse eines float64 enthält bei realen Messwerten in den unteren Bits praktisch Zufall. Dieselben Werte auf zwei Nachkommastellen gerundet und als float32 gespeichert erreichen 2,15 bis 3,3. Komprimiert belegen sie mit zstd -3 dann 27 statt 105 MB, ein Viertel.
Wer Sensordaten, Simulationsergebnisse oder Finanzzeitreihen sichert, gewinnt durch sinnvolles Runden vor dem Speichern mehr als durch jede Kompressionsstufe. Deshalb bringen wissenschaftliche Formate wie HDF5 oder Parquet eigene Kodierungen für Gleitkommazahlen mit.
VM-Images: der Container ist egal
Dasselbe ext4-Dateisystem liefert als qcow2, VMDK, VDI und ISO fast identische Raten: 2,95 bis 3,00 mit zstd -3 und 3,8 bis 3,9 mit xz -6. Die Containerformate speichern nur belegte Cluster, der Inhalt ist in allen gleich. Das Raw-Image mit 512 MB erreicht dagegen 7,5 (zstd -3) bis 9,9 (xz -6), weil seine unbelegten Nullbereiche fast nichts kosten. Ohne die Nullen komprimiert der Inhalt wie in den Containerformaten.
Das qcow2 mit interner Kompression (qemu-img convert -c) ist bereits 78 statt 200 MB groß und schrumpft kaum weiter (1,01 bis 1,03). Die Wahl lautet also: qcow2 intern komprimieren und das Backup schnell durchlaufen lassen, oder unkomprimiert speichern und die Kompression dem Backup überlassen. zstd -3 erreicht auf dem unkomprimierten qcow2 eine Rate von 2,95 und damit mehr als die interne Kompression von qcow2 mit 2,56.
Archive und bereits komprimierte Daten
Das unkomprimierte tar des VM-Baums verhält sich wie das qcow2 (2,9 bis 3,8). Derselbe Baum als tar.gz oder ZIP ist 68 bis 69 MB groß und bleibt bei 1,00 bis 1,03. Git-Objekte sind zlib-komprimiert und erreichen 1,00 bis 1,08. Die Mailbox mit 35 Prozent Base64-Anhängen liegt bei 1,3 bis 2,75: Der Text komprimiert, die Base64-kodierten JPEGs kaum.
Die vollständige Tabelle
| Datei | MB | lz4 -1 | gzip -6 | zstd -1 | zstd -3 | zstd -9 | zstd -19 | bzip2 -9 | xz -6 | zstd -3 MB/s |
|---|---|---|---|---|---|---|---|---|---|---|
| Text/Logs | ||||||||||
| Nginx-Access-Log | 40 | 4,45 | 7,89 | 7,01 | 6,86 | 8,65 | 10,02 | 12,97 | 10,18 | 245 |
| Syslog | 40 | 3,43 | 5,67 | 5,45 | 5,32 | 6,09 | 7,05 | 8,29 | 7,05 | 180 |
| Strukturiert | ||||||||||
| XML | 91 | 4,79 | 7,86 | 8,04 | 8,32 | 9,85 | 13,01 | 15,87 | 13,31 | 273 |
| JSON Lines | 66 | 3,57 | 6,03 | 5,97 | 6,22 | 7,30 | 9,76 | 11,76 | 10,01 | 216 |
| CSV | 31 | 2,17 | 3,54 | 3,33 | 3,51 | 4,08 | 5,04 | 5,82 | 5,25 | 134 |
| Quellcode | ||||||||||
| Go (klauspost/compress) | 5 | 4,05 | 6,66 | 6,11 | 6,90 | 8,17 | 9,19 | 8,17 | 9,39 | 194 |
| Python (stdlib) | 61 | 2,86 | 4,59 | 4,26 | 4,69 | 5,56 | 6,50 | 5,85 | 6,66 | 166 |
| Datenbank | ||||||||||
| MySQL-Dump (SQL) | 36 | 2,40 | 3,85 | 3,59 | 3,85 | 4,35 | 5,71 | 6,69 | 5,95 | 146 |
| SQLite-Datei | 42 | 2,10 | 3,08 | 2,76 | 3,23 | 3,71 | 4,44 | 4,83 | 4,82 | 141 |
| Text/Web | ||||||||||
| HTML-Seiten | 41 | 1,81 | 3,00 | 2,80 | 3,48 | 4,55 | 6,68 | 4,58 | 6,79 | 127 |
| Text/Mail | ||||||||||
| Mailbox (mbox) | 48 | 1,00 | 1,32 | 1,37 | 1,65 | 1,96 | 2,72 | 1,36 | 2,75 | 254 |
| Office | ||||||||||
| Excel .xls (BIFF) | 48 | 1,87 | 3,11 | 3,51 | 3,29 | 3,47 | 4,33 | 3,85 | 5,68 | 141 |
| Excel .xlsx | 21 | 1,00 | 1,01 | 1,00 | 1,00 | 1,02 | 1,04 | 1,01 | 1,04 | 293 |
| Word .docx (12 Dateien) | 45 | 1,00 | 1,00 | 1,00 | 1,00 | 1,01 | 1,17 | 1,01 | 1,17 | 476 |
| PowerPoint .pptx (8 Dateien) | 30 | 1,00 | 1,01 | 1,00 | 1,00 | 1,01 | 1,01 | 1,01 | 1,01 | 454 |
| Dokumente | ||||||||||
| PDF, Text | 2 | 1,10 | 1,36 | 1,36 | 1,37 | 1,37 | 1,38 | 1,37 | 1,37 | 134 |
| PDF, gescannt (JPEG) | 19 | 1,00 | 1,23 | 1,24 | 1,24 | 1,24 | 1,24 | 1,23 | 1,23 | 236 |
| Bilder | ||||||||||
| JPEG-Fotos | 15 | 1,00 | 1,00 | 1,00 | 1,00 | 1,00 | 1,00 | 1,02 | 1,00 | 417 |
| PNG | 47 | 1,00 | 1,00 | 1,00 | 1,00 | 1,00 | 1,00 | 1,00 | 1,00 | 478 |
| BMP (unkomprimiert) | 84 | 1,00 | 1,06 | 1,04 | 1,04 | 1,05 | 1,10 | 1,23 | 1,29 | 226 |
| TIFF (unkomprimiert) | 84 | – | 1,06 | – | 1,04 | – | 1,10 | – | 1,29 | 259 |
| Medien | ||||||||||
| WAV (PCM) | 30 | 1,00 | 1,07 | 1,06 | 1,06 | 1,06 | 1,06 | 1,06 | 1,15 | 220 |
| FLAC | 19 | 1,00 | 1,00 | 1,00 | 1,00 | 1,00 | 1,00 | 1,00 | 1,00 | 456 |
| MP3 | 4 | 1,00 | 1,00 | 1,00 | 1,00 | 1,00 | 1,01 | 1,01 | 1,00 | 155 |
| MP4 (H.264) | 27 | 1,00 | 1,01 | 1,00 | 1,00 | 1,00 | 1,02 | 1,00 | 1,02 | 184 |
| Numerik | ||||||||||
| Messdaten float64 | 114 | 1,00 | 1,13 | 1,09 | 1,09 | 1,09 | 1,20 | 1,08 | 1,30 | 269 |
| Messdaten float32, gerundet | 57 | 1,50 | 2,37 | 1,54 | 2,15 | 2,31 | 2,67 | 2,92 | 3,31 | 101 |
| System | ||||||||||
| Linux-Binaries (ELF) | 93 | 1,75 | 2,48 | 2,18 | 2,40 | 2,62 | 3,01 | 2,56 | 3,27 | 148 |
| Schriften (TTF) | 43 | 1,30 | 1,60 | 1,47 | 1,75 | 1,93 | 2,10 | 1,66 | 2,22 | 144 |
| Git-Objekte | 38 | 1,00 | 1,00 | 1,01 | 1,05 | 1,06 | 1,08 | 1,01 | 1,08 | 433 |
| VM-Images | ||||||||||
| qcow2 | 200 | 2,17 | 2,95 | 2,78 | 2,95 | 3,22 | 3,69 | 3,59 | 3,86 | 183 |
| qcow2 (intern komprimiert) | 78 | 1,00 | 1,01 | 1,01 | 1,01 | 1,01 | 1,03 | 1,01 | 1,02 | 425 |
| VMDK | 200 | – | 2,94 | – | 2,95 | – | – | – | 3,85 | 138 |
| VDI | 203 | – | 2,99 | – | 3,00 | – | – | – | 3,91 | 191 |
| Raw (ext4, 512 MB) | 512 | 5,49 | 7,50 | 7,11 | 7,55 | 8,24 | – | 9,19 | 9,86 | 369 |
| ISO 9660 | 201 | 2,18 | 2,95 | 2,78 | 2,96 | 3,23 | – | 3,60 | 3,82 | 184 |
| Archive | ||||||||||
| tar (unkomprimiert) | 199 | 2,17 | 2,93 | 2,77 | 2,94 | 3,21 | 3,66 | 3,58 | 3,79 | 189 |
| Server-Backup-Mix (tar) | 177 | 1,89 | 2,49 | 2,35 | 2,55 | 2,79 | 3,18 | 2,85 | 3,29 | 174 |
| tar.gz | 68 | 1,00 | 1,00 | 1,00 | 1,00 | 1,00 | 1,01 | 1,00 | 1,01 | 518 |
| ZIP | 69 | 1,00 | 1,00 | 1,00 | 1,00 | 1,01 | 1,03 | 1,00 | 1,03 | 436 |
| Silesia | ||||||||||
| dickens (Literatur) | 10 | 1,58 | 2,63 | 2,39 | 2,78 | 3,11 | 3,58 | 3,64 | 3,60 | 110 |
| mozilla (Programmdateien) | 49 | 1,94 | 2,69 | 2,55 | 2,77 | 3,02 | 3,39 | 2,86 | 3,79 | 174 |
| mr (MRT-Bild) | 10 | 1,83 | 2,70 | 2,61 | 2,81 | 3,00 | 3,20 | 4,08 | 3,63 | 129 |
| nci (Chemie-Datenbank) | 32 | 6,06 | 10,49 | 11,76 | 11,80 | 14,93 | 19,87 | 18,51 | 18,86 | 307 |
| ooffice (Windows-DLL) | 6 | 1,42 | 1,99 | 1,71 | 1,96 | 2,14 | 2,37 | 2,15 | 2,54 | 119 |
| osdb (MySQL-Datenbank) | 10 | 1,92 | 2,70 | 2,70 | 2,88 | 3,02 | 3,26 | 3,60 | 3,54 | 150 |
| reymont (PDF) | 6 | 2,08 | 3,57 | 3,08 | 3,41 | 3,97 | 4,92 | 5,32 | 5,03 | 99 |
| samba (C-Quellcode) | 21 | 2,80 | 3,96 | 3,92 | 4,34 | 4,93 | 5,53 | 4,75 | 5,70 | 189 |
| sao (Sternkatalog) | 7 | 1,07 | 1,36 | 1,16 | 1,31 | 1,39 | 1,45 | 1,47 | 1,64 | 100 |
| webster (Wörterbuch, HTML) | 40 | 2,06 | 3,40 | 3,03 | 3,42 | 4,04 | 4,77 | 4,80 | 4,80 | 133 |
| x-ray (Röntgenbild) | 8 | 1,01 | 1,40 | 1,25 | 1,39 | 1,58 | 1,64 | 2,09 | 1,89 | 94 |
| xml (XML-Dateien) | 5 | 4,35 | 7,72 | 7,66 | 8,36 | 10,29 | 11,75 | 12,12 | 11,79 | 244 |
| Extremfälle | ||||||||||
| AES-verschlüsselt | 36 | 1,00 | 1,00 | 1,00 | 1,00 | 1,00 | 1,00 | 1,00 | 1,00 | 488 |
| Zufallsdaten | 40 | 1,00 | 1,00 | 1,00 | 1,00 | 1,00 | 1,00 | 1,00 | 1,00 | 493 |
| Nullbytes | 128 | 255 | 1.030 | 29.440 | 31.783 | 32.217 | 32.435 | 1.198.373 | 6.827 | 1.208 |
Ein Strich bedeutet, dass die Kombination nicht gemessen wurde; betroffen sind nur Formate, deren Inhalt einer bereits gemessenen Datei entspricht (VMDK und VDI entsprechen qcow2, TIFF entspricht BMP).
Ergebnisse nach Verfahren und Stufe
Über das Kernset von 45 Dateien liegt die mittlere Rate zwischen 1,64 (lz4 -1) und 3,02 (xz -9), der Kompressionsdurchsatz auf einem Kern zwischen 1,6 MB/s (xz -9) und 484 MB/s (lz4 -1). Das ist ein Faktor 1,8 bei der Rate gegen einen Faktor 300 beim Tempo. Die Dekompression streut weniger: zwischen 19 MB/s (bzip2) und 1.203 MB/s (lz4).
| Verfahren | Rate (geom. Mittel) | Kompression MB/s | Dekompression MB/s | Speicher max. |
|---|---|---|---|---|
| lz4 -1 | 1,64 | 484 | 1.203 | 13 MB |
| gzip -1 | 1,97 | 44 | 133 | 13 MB |
| gzip -6 | 2,17 | 24 | 144 | 13 MB |
| zstd -1 | 2,07 | 237 | 911 | 17 MB |
| zstd -3 | 2,20 | 203 | 832 | 53 MB |
| zstd -9 | 2,40 | 61 | 808 | 108 MB |
| zstd -19 | 2,69 | 1,9 | 647 | 227 MB |
| brotli -6 | 2,40 | 24 | 339 | 100 MB |
| bzip2 -9 | 2,65 | 11 | 19 | 13 MB |
| xz -1 | 2,37 | 7 | 43 | 13 MB |
| xz -6 | 2,81 | 1,9 | 44 | 95 MB |
| xz -9 | 3,02 | 1,6 | 44 | 675 MB |
Faktor 1,8 bei der Rate, Faktor 300 beim Tempo
- zstd, die Linie verbindet die Stufen 19, 9, 3 und 1
- übrige Verfahren, Linien verbinden die Stufen von gzip und xz
zstd gegen gzip: gleiche Rate, achtfaches Tempo
zstd -3 erreicht im Mittel mit 2,20 etwas mehr als gzip -6 mit 2,17, komprimiert aber mit 203 statt 24 MB/s und dekomprimiert mit 832 statt 144 MB/s. Selbst zstd -1 schlägt gzip -1 bei Rate (2,07 gegen 1,97) und Tempo (237 gegen 44 MB/s). Deutlich vorn liegt gzip -6 nur bei den Logs und den gerundeten Messdaten (7 bis 15 Prozent höhere Rate), knapp auch bei einigen Programm- und Messdateien (2 bis 5 Prozent).
Der Sweep bestätigt das auf dem Server-Mix: gzip -6 erreicht dort 4,06 bei 36 MB/s, zstd -3 3,99 bei 171 MB/s und zstd -5 4,14 bei 86 MB/s. Die gzip-Stufen 7 bis 9 lohnen sich nicht: Stufe 9 bringt gegenüber Stufe 6 nur 1,5 Prozent mehr und ist fast fünfmal so langsam (7,6 statt 36 MB/s).
zstd gegen xz: der Preis der letzten 30 Prozent
xz -6 erreicht mit 2,81 eine um 28 Prozent höhere Rate als zstd -3, braucht aber 107-mal so lange. zstd -19 liegt mit 2,69 nur 4 Prozent unter xz -6, ist genauso langsam und braucht mehr Speicher. xz -9 ist mit 3,02 das Maximum des Tests, benötigt aber 675 MB Arbeitsspeicher und bringt gegenüber xz -6 nur 7 Prozent, fast ausschließlich durch das größere Wörterbuch.
Der Stufen-Sweep
Auf dem 64-MB-Server-Mix flacht die zstd-Kurve ab Stufe 9 deutlich ab; erst die Stufen 16 bis 19 mit größerem Fenster und optimalem Parsing bringen wieder mehr, zu sehr hohen Kosten. xz zeigt dasselbe Muster: Ab Stufe 7 wachsen nur noch Wörterbuch und Speicher.
| Konfiguration | Rate | Kompression MB/s |
|---|---|---|
| zstd -3 | 3,99 | 171 |
| zstd -5 | 4,14 | 86 |
| zstd -9 | 4,46 | 46 |
| zstd -12 | 4,56 | 25 |
| zstd -15 | 4,67 | 5 |
| zstd -16 bis -19 | 4,85 bis 5,18 | 3,6 bis 1,5 |
| zstd -20 und -22 | 5,20 | unter 1,5 |
| gzip -6 | 4,06 | 36 |
| gzip -9 | 4,12 | 7,6 |
| xz -0 | 4,18 | 20 |
| xz -3 | 4,67 | 5,7 |
| xz -6 | 5,39 | 1,9 |
| xz -7 bis -9 | 5,41 | unter 1,9 |
| brotli -11 | 5,38 | 0,43 |
Zusammen bilden die Sweep-Kurven eine Grenze, hinter der kein Verfahren liegt: lz4 für höchstes Tempo, zstd 1 bis 9 für 50 bis 350 MB/s, zstd 10 bis 19 und bzip2 für 2 bis 30 MB/s, xz 5 bis 9 und brotli 11 für maximale Rate unter 2 MB/s. gzip liegt in jeder Stufe unterhalb der zstd-Kurve. brotli -11 bräuchte für ein 1-TB-Backup 27 Tage; es ist für Webseiten gebaut, die einmal komprimiert und millionenfach ausgeliefert werden.
Dekompression: die vergessene Hälfte
Beim Restore zählt die Dekompression. zstd dekomprimiert mit 650 bis 910 MB/s, fast unabhängig von der Stufe. gzip schafft 130 bis 145 MB/s, xz 43 bis 44 MB/s, bzip2 nur 19 MB/s.
Ein 500-GB-Restore braucht mit zstd auf einem Kern knapp zehn Minuten reine Dekompressionszeit, mit gzip eine Stunde, mit xz drei Stunden, mit bzip2 sieben Stunden. LZ77-Dekoder kopieren nur Bytes; zstd gewinnt zusätzlich durch die tabellenbasierte Entropiekodierung. bzip2 muss die Burrows-Wheeler-Transformation mit zufälligen Speicherzugriffen umkehren, xz den Range-Coder Bit für Bit nachrechnen.
Speicherbedarf
Die Spitzenwerte reichen von 13 MB (lz4, gzip, bzip2, xz -1) über 53 MB (zstd -3) und 95 MB (xz -6) bis 675 MB (xz -9). Für einen Backup-Client auf einem kleinen Server oder in einem Container ist das relevant: xz -9 kann auf einem System mit 1 GB RAM bereits scheitern.
Das Fenster-Experiment
Um die Fenstergrößen sichtbar zu machen, wurde ein 16-KiB-Block aus Zufallsdaten zweimal in eine Datei geschrieben, getrennt durch 16 KiB bis 256 MiB weiterer Zufallsdaten. Ein Kompressor, dessen Fenster den Abstand abdeckt, spart die zweite Kopie fast vollständig ein; einer, dessen Fenster zu klein ist, spart nichts.
| Verfahren | 16 KiB | 64 KiB | 1 MiB | 4 MiB | 16 MiB | 64 MiB | 256 MiB | Fenster laut Doku |
|---|---|---|---|---|---|---|---|---|
| gzip -9 | ja | nein | nein | nein | nein | nein | nein | 32 KiB |
| lz4 -9 | ja | nein | nein | nein | nein | nein | nein | 64 KiB |
| bzip2 -9 | 73 % | 51 % | nein | nein | nein | nein | nein | 900-KB-Block |
| zstd -3 | ja | ja | ja | nein | nein | nein | nein | 2 MiB |
| brotli -6 | ja | ja | ja | nein | nein | nein | nein | 4 MiB |
| xz -1 | ja | ja | ja | nein | nein | nein | nein | 1 MiB |
| xz -6 | ja | ja | ja | ja | nein | nein | nein | 8 MiB |
| zstd -19 | ja | ja | ja | ja | nein | nein | nein | 8 MiB |
| xz -9 | ja | ja | ja | ja | ja | ja | nein | 64 MiB |
| zstd -3 --long=28 | ja | ja | ja | ja | ja | ja | nein | 256 MiB |
Die Messung deckt sich mit den dokumentierten Fenstergrößen. bzip2 ist der Sonderfall: Es arbeitet nicht mit Verweisen, sondern sortiert, und spart deshalb auch innerhalb seines Blocks nur 73 Prozent der zweiten Kopie ein. Wiederholungen im Abstand von 16 MiB und mehr erkennen nur xz -9 und zstd mit --long. Der Client liegt mit seinem 8-MiB-Fenster bei ZSTD und LZMA2 in der Zeile von xz -6, mit GZIP in der Zeile von gzip -9.
Das Versions-Experiment: zwei Stände, ein Archiv
Der praktische Fall dahinter: In einem Archiv liegen zwei Versionen desselben Quellbaums mit 61 MB, in der zweiten sind 3 Prozent der Dateien geändert. Das kommt in Backups ständig vor, etwa bei Projektkopien, Release-Verzeichnissen, Container-Images mit gemeinsamen Schichten oder Dokumenten in mehreren Fassungen.
| Verfahren | Eine Version | Zwei Versionen | Zweite Kopie erkannt | Tempo |
|---|---|---|---|---|
| gzip -6 | 4,61 | 4,61 | nein | 26 MB/s |
| zstd -3 | 4,70 | 4,70 | nein | 172 MB/s |
| zstd -3 --long=27 | 4,94 | 9,78 | ja | 191 MB/s |
| zstd -19 | 6,53 | 6,54 | nein | 1,7 MB/s |
| zstd -19 --long=27 | 6,70 | 13,27 | ja | 2,3 MB/s |
| xz -6 | 6,69 | 6,70 | nein | 1,9 MB/s |
| xz -9 | 6,97 | 13,87 | ja | 1,7 MB/s |
Mit einem 128-MiB-Fenster erkennt zstd -3 die zweite Version fast vollständig und verdoppelt die Rate auf 9,78, ohne langsamer zu werden. xz -9 erreicht mit 13,87 die höchste Rate, braucht dafür aber über hundertmal so lange. Bei redundanten Daten ist die Fenstergröße wichtiger als die Stufe. Mit seinem festen Fenster von 8 MiB würde der Client die zweite Version hier noch einmal speichern, denn die beiden Stände liegen 61 MB auseinander.
Gegenprobe: der lionbackup-Client selbst
Der Haupttest misst die Referenzwerkzeuge. Der Client verwendet Go-Bibliotheken mit eigenen Stufen, deshalb haben wir nachgemessen: mit dem Client aus dem aktuellen Entwicklungsstand (Version 0.1.35) auf einem Notebook-Prozessor mit 10 Kernen und 12 Threads. Die vier Quellen bestehen aus echten Daten:
- Systemprotokoll: 60 MB Export des Systemjournals des Testrechners
- Projektdateien: 17 MB aus unserem eigenen Repository, überwiegend PHP, YAML- und Ansible-Vorlagen und Go, zu einem Viertel Webschriften
- Programme: 36 MB Linux-Bibliotheken und Programme
- Bilder: 69 MB Hintergrundbilder von Ubuntu als JPEG und PNG
Raten: ZSTD wie zstd -3, LZMA2 deutlich unter xz
Die Raten stammen aus --autotune mit compression_level 1, 5 und 9. Die letzten beiden Spalten zeigen die Referenzwerkzeuge auf denselben tar-Strömen.
| Quelle | Größe | ZSTD 1 | ZSTD 5 | ZSTD 9 | GZIP 5 | LZMA2 | zstd -3 | xz -6 |
|---|---|---|---|---|---|---|---|---|
| Systemprotokoll | 60 MB | 15,7 | 21,1 | 32,5 | 6,2 | 18,6 | 13,3 | 37,3 |
| Projektdateien | 17 MB | 2,61 | 2,73 | 2,98 | 2,52 | 2,89 | 2,77 | 3,14 |
| Programme | 36 MB | 2,24 | 2,40 | 2,62 | 2,33 | 2,64 | 2,45 | 3,18 |
| Bilder | 69 MB | 1,00 | 1,00 | 1,01 | 1,00 | 1,01 | 1,01 | 1,01 |
Drei Ergebnisse stechen heraus. ZSTD auf Stufe 5 komprimiert wie zstd -3, Stufe 9 liegt zwischen zstd -7 und zstd -11. Beim Systemprotokoll liegt der Client mit 21,1 sogar weit vor zstd -3 mit 13,3: Sein Fenster ist mit 8 MiB viermal so groß und erfasst Meldungen, die sich in größerem Abstand wiederholen; mit demselben Fenster kommt auch zstd -3 auf 20,2.
LZMA2 im Client erreicht nicht die Raten von xz. Die Go-Bibliothek sucht weniger gründlich als das Referenzwerkzeug: Beim Systemprotokoll kommt sie auf die Hälfte von xz -6, bei den Programmen auf 2,64 statt 3,18. ZSTD auf Stufe 9 erreicht in allen vier Quellen praktisch dieselbe oder eine höhere Rate (bei den Programmen 2,62 gegen 2,64).
GZIP liegt bei allen komprimierbaren Quellen hinter ZSTD: bei Projektdateien und Programmen um 3 bis 8 Prozent, beim Systemprotokoll erreicht ZSTD mehr als die dreifache Rate. Hier fehlt GZIP das Fenster: 32 KiB reichen für die Wiederholungen im Journal nicht.
Tempo: GZIP packt schneller, ZSTD entpackt viel schneller
Für die Durchsätze haben wir die Bibliotheken mit genau den Einstellungen des Clients aufgerufen und jede Messung dreimal wiederholt (Median, auf zwei Stellen gerundet). „Entpacken“ entspricht dem Restore nach dem Entschlüsseln.
| Komprimieren in MB/s | Systemprotokoll | Projektdateien | Programme | Bilder |
|---|---|---|---|---|
| ZSTD, Stufe 1 | 700 | 350 | 280 | 1.400 |
| ZSTD, Stufe 5 | 760 | 250 | 220 | 1.100 |
| ZSTD, Stufe 9 | 120 | 44 | 21 | 55 |
| GZIP, Stufe 5 | 850 | 570 | 390 | 2.100 |
| LZMA2 | 44 | 7,4 | 6,4 | 1,1 |
| Entpacken in MB/s | Systemprotokoll | Projektdateien | Programme | Bilder |
|---|---|---|---|---|
| ZSTD, Stufe 5 | 3.600 | 1.200 | 1.200 | 5.400 |
| GZIP, Stufe 5 | 500 | 350 | 220 | 3.300 |
| LZMA2 | 190 | 51 | 27 | 33 |
GZIP nutzt alle zwölf Threads und komprimiert deshalb 1,1- bis 2,3-mal so schnell wie ZSTD. ZSTD kommt bei den Projektdateien und Programmen nicht über das Tempo von zstd -3 auf einem Kern hinaus. Beim Entpacken dreht sich das Bild: Auf den komprimierbaren Quellen ist ZSTD drei- bis siebenmal so schnell wie GZIP und 18- bis 44-mal so schnell wie LZMA2.
Stufe 1 ist bei ZSTD höchstens 40 Prozent schneller als Stufe 5, beim Systemprotokoll sogar langsamer, liefert aber 5 bis 35 Prozent größere Archive. Stufe 9 macht die Archive der Projektdateien und Programme um 8 Prozent kleiner, das Systemprotokoll um ein Drittel, braucht dafür aber das Fünf- bis Zehnfache an Zeit.
LZMA2 bricht bei Daten ein, die sich nicht komprimieren lassen: Die Bilder liefen mit 1,1 MB/s durch. Ein Fotoarchiv von 100 GB bräuchte so über einen Tag, ohne nennenswert kleiner zu werden.
Was das für den Backup-Lauf heißt
Ob das schnellere Packen von GZIP zählt, entscheidet die Leitung. Bei 100 Mbit/s Upload ist ZSTD in jeder Quelle mindestens so schnell fertig wie GZIP, weil weniger Bytes übertragen werden; beim Systemprotokoll mehr als dreimal so schnell. Das gilt in der Gegenprobe bis 500 Mbit/s. Erst oberhalb von etwa 750 Mbit/s schließt GZIP Projektdateien und Programme auf diesem Rechner früher ab, weil es alle Threads nutzt. Dafür belegt das Backup mehr Speicherplatz, und der Restore dauert dreieinhalb- bis fünfeinhalbmal so lange.
Warum --autotune manchmal GZIP empfiehlt
Die Empfehlung von --autotune ist das Verfahren mit dem kleinsten Produkt aus Größe und Laufzeit beim Komprimieren. Restore-Tempo und Speicherkosten fließen nicht ein, und die Laufzeit beim Packen bevorzugt auf Rechnern mit vielen Kernen GZIP. In der Gegenprobe empfahl --autotune für das Systemprotokoll ZSTD, für Projektdateien, Programme und Bilder GZIP. So sieht die Ausgabe für die Projektdateien aus:
Quelle: /var/tmp/kx-gegenprobe/c/code
Unkomprimiert (tar): 16.5 MB Level: 5 CPUs: 12
Methode Größe Ratio Zeit Durchsatz
-----------------------------------------------------
ZSTD 6.0 MB 36.7% 78ms 223.1 MB/s
GZIP 6.6 MB 39.7% 45ms 381.8 MB/s
LZMA2 5.7 MB 34.6% 2.339s 7.4 MB/s
Kleinste Größe : LZMA2 (5.7 MB)
Schnellste : GZIP (45ms)
Empfehlung : GZIP (bestes Verhältnis aus Größe und Zeit)
→ in der Config setzen: compression_method: GZIPDie Spalte „Ratio“ ist die Größe in Prozent des Originals; 36,7 Prozent entsprechen einer Rate von 2,73. Größen gibt --autotune in Binäreinheiten aus: 16.5 MB sind 17,3 Millionen Bytes. Lesen Sie die Tabelle als Messung, nicht als Urteil: Für die meisten Anschlüsse sind die kleinere Datei und der schnellere Restore wichtiger als die Sekunden beim Packen.
Warum manche Daten nicht kleiner werden
Von den 55 Testdateien bleiben 12 bei jedem Verfahren und jeder Stufe unter einer Rate von 1,05, mit zstd -3 sind es 16. Das ist kein Versagen der Kompressoren, sondern eine Eigenschaft der Daten. Es gibt vier Gründe, jeder mit eigener Signatur.
Grund 1: Die Entropiekodierung ist schon passiert
JPEG, PNG, MP3, MP4, FLAC, ZIP, gzip, Git-Objekte, .docx, .xlsx, .pptx, die meisten PDFs und intern komprimierte qcow2-Images haben eines gemeinsam: Am Ende ihrer Verarbeitungskette steht ein Entropiekodierer. Bei JPEG und MP3 ist das Huffman, bei PNG, ZIP und Office-Dateien Deflate, bei H.264 CABAC, bei FLAC Rice-Codes. Ein Entropiekodierer erzeugt einen Bitstrom, in dem jedes Bit annähernd gleich wahrscheinlich 0 oder 1 ist. Für den nächsten Kompressor sieht das aus wie Zufall.
Übrig bleiben die unkomprimierten Teile des Containers: Dateinamen und Verzeichnisse im ZIP, Objektstrukturen im PDF, Metadaten im MP4. Deshalb erreicht der ZIP-Container 1,00 bis 1,03, das Text-PDF 1,37 und das Scan-PDF 1,24. Bei großen Fenstern kommen manchmal Prozente hinzu, wenn sich identische Objekte wiederholen, etwa dasselbe Bild in zwölf Word-Dateien.
Für ein Backup heißt das: Ein Verzeichnis mit Fotos, Videos, Musik und Office-Dokumenten hat eine Gesamtrate nahe 1,0. Hier zählt nur, wie schnell der Kompressor die Daten durchreicht. zstd -3 lief über die JPEG-Fotos mit 417 MB/s und über die PNG-Bilder mit 478 MB/s; zstd -19 brauchte für dieselben Dateien bei identischem Ergebnis bis zu 150-mal so lange.
Grund 2: Verschlüsselung ist Zufall mit Schlüssel
Der AES-verschlüsselte MySQL-Dump erreicht exakt 1,00 bei allen zwölf Verfahren, obwohl dieselben Daten unverschlüsselt eine Rate von 3,9 bis 6,7 erreichen. Das ist beabsichtigt: Eine Chiffre, deren Ausgabe sich von Zufall unterscheiden ließe, wäre gebrochen.
Daraus folgt die Reihenfolge im lionbackup-Client: erst komprimieren, dann verschlüsseln. Dasselbe gilt für jede verschlüsselte Quelle im Backup: LUKS-Volumes, BitLocker-Container, verschlüsselte Datenbank-Tablespaces, age- oder GPG-Dateien, Passwort-Tresore. Sie bleiben bei Rate 1,00 und sollten das Backup so schnell wie möglich durchlaufen.
Grund 3: Rauschen ist Information
Unkomprimierte Formate sind nicht automatisch komprimierbar. Die BMP- und TIFF-Bilder (1,04 bis 1,29), die WAV-Datei (1,06 bis 1,15), die float64-Messdaten (1,09 bis 1,30) und die Zufallsdaten (1,00) enthalten Rauschen, und Rauschen ist aus Sicht der Informationstheorie echte Information: Es lässt sich nicht vorhersagen und deshalb nicht kürzer schreiben.
Bei Fotos stammt das Rauschen vom Bildsensor, bei Audio vom Mikrofon und der Quantisierung, bei Messdaten von der Messung selbst und von den überzähligen Mantissenbits. Spezialisierte Verfahren wie PNG, FLAC oder die Gleitkomma-Kodierer in HDF5 helfen, weil sie das Signal unter dem Rauschen vorhersagen und nur die Differenz speichern. Ein Allzweckkompressor kann das nicht. Bei Messdaten hilft vor allem, nur die Stellen zu speichern, die tatsächlich gemessen wurden.
Grund 4: Base64 verschenkt zwei Bit pro Byte
E-Mail-Anhänge, JSON-Felder mit eingebetteten Bildern, Zertifikate und viele API-Antworten enthalten Binärdaten als Base64. Base64 verwendet 64 Zeichen, also 6 Bit Information pro 8-Bit-Zeichen. Ein Kompressor kann Base64-Text deshalb auf 75 Prozent bringen (Rate 1,33), aber nicht weiter, wenn der kodierte Inhalt selbst schon komprimiert ist. Die Testmailbox mit 35 Prozent Base64-Anteil erreicht 1,65 (zstd -3): Der Text schrumpft stark, die Anhänge auf bestenfalls drei Viertel.
Der Overhead bei doppelter Kompression
Bereits komprimierte Daten werden durch einen zweiten Kompressor minimal größer. Der Rahmen kostet bei den 40 MB Zufallsdaten mit zstd 0,002 Prozent (973 Bytes), mit gzip 0,02 Prozent, mit xz 0,005 Prozent und mit bzip2 0,45 Prozent (187 KB). Der Platz ist also kein Problem, die Zeit schon: zstd -19 und xz -6 suchen in Zufallsdaten genauso lange nach Wiederholungen wie in Text und finden nichts.
zstd hat dafür eine Abkürzung eingebaut: Findet es in einem Block keine Wiederholungen, speichert es ihn roh und beschleunigt. zstd -3 lief über die AES-Datei mit 488 MB/s, über das Syslog mit 180 MB/s. xz kennt diese Abkürzung nicht und braucht für Zufallsdaten mit 1,9 MB/s genauso lange wie für alles andere.
Das andere Extrem: Nullbytes
Das andere Extrem zeigt die Obergrenzen der Formate. 128 MiB Nullbytes schrumpfen mit gzip auf 130 KB (Rate 1.030), mit xz auf 19,7 KB (6.827), mit zstd auf 4,1 KB (32.435), mit bzip2 auf 112 Bytes (1,2 Millionen) und mit brotli auf 102 Bytes (1,3 Millionen). Die Unterschiede stammen aus dem Format: Deflate kann pro Verweis höchstens 258 Bytes kopieren und braucht für 128 MiB über 500.000 Verweise, zstd speichert jeden 128-KiB-Block aus gleichen Bytes als RLE-Block von 4 Bytes, brotli erlaubt Kopien von bis zu 16 MiB, und bzip2 bringt eine Lauflängenkodierung mit.
In der Praxis treten solche Folgen in Disk-Images, vorbelegten Datenbankdateien und Sparse-Dateien auf. Die Obergrenze ist egal, weil schon eine Rate von 1.000 den Nullbereich auf ein Promille bringt. Wichtig ist, dass alle Verfahren Nullen schnell verarbeiten: zstd -3 lief hier mit 1.208 MB/s, bzip2 mit 126 MB/s.
Empfehlungen für die Praxis
Aus Messung und Gegenprobe ergeben sich sechs Regeln. Die ersten vier betreffen die Einstellungen des Clients, die letzten beiden gelten für jedes Backup.
Regel 1: ZSTD wählen und ausdrücklich eintragen
ZSTD lieferte in der Gegenprobe bei jeder komprimierbaren Quelle kleinere Archive als GZIP, beim Systemprotokoll knapp ein Drittel der Größe, und stellte drei- bis siebenmal so schnell wieder her. Mit 220 bis 760 MB/s auf komprimierbaren Daten packt es schneller, als die meisten Anschlüsse übertragen; ein Anschluss mit 1 Gbit/s nimmt 125 MB/s ab.
Tragen Sie compression_method: ZSTD ausdrücklich ein. Fehlt der Eintrag, komprimiert der Client mit GZIP. Wenn --autotune GZIP empfiehlt, liegt das an der Gewichtung des Packtempos (siehe Gegenprobe); GZIP war in der Gegenprobe erst oberhalb von etwa 750 Mbit/s Upload früher fertig und stellt auch dann deutlich langsamer wieder her.
Regel 2: Die Stufe 5 beibehalten
Stufe 5 ist der Standard und für fast alle Daten richtig. Stufe 1 spart bei ZSTD höchstens 40 Prozent Zeit und kostet 5 bis 35 Prozent mehr Speicherplatz. Stufe 9 lohnt sich für Text, Logs und Quellcode hinter einer schmalen Leitung oder wenn Speicherplatz knapp ist: Die Archive werden 8 bis 35 Prozent kleiner, das Packen dauert fünf- bis zehnmal so lange. In der Gegenprobe war ein Lauf mit Stufe 9 nur bei schmaler Leitung insgesamt früher fertig: für die Projektdateien unterhalb von etwa 130 Mbit/s Upload, für Programme unterhalb von etwa 70 Mbit/s, für das Systemprotokoll unterhalb von etwa 50 Mbit/s.
Regel 3: LZMA2 nur in Ausnahmefällen
Im Haupttest erreicht xz -6 eine um 28 Prozent höhere Rate als zstd -3. Im Client gilt das nicht: Seine LZMA2-Bibliothek erreicht auf komprimierbaren Daten nur 50 bis 92 Prozent der Rate von xz -6; ZSTD auf Stufe 9 komprimiert praktisch genauso stark oder stärker und ist knapp drei- bis sechsmal so schnell, bei Bildern 50-mal. LZMA2 entpackt 18- bis 44-mal langsamer als ZSTD und verarbeitet Daten, die nicht schrumpfen, mit rund 1 MB/s. Wer heute LZMA2 eingetragen hat, wechselt besser auf ZSTD, bei schmaler Leitung mit compression_level: 9; ältere Sicherungen bleiben lesbar, weil der Client das Verfahren beim Restore selbst erkennt.
Regel 4: Bereits Komprimiertes durchreichen
Fotos, Videos, Musik, fertige Archive, aktuelle Office-Dateien und verschlüsselte Container bleiben bei Rate 1,0. ZSTD reicht sie auf den Stufen 1 bis 5 mit über 1 GB/s durch; sie können deshalb mit anderen Daten in einer Konfiguration bleiben. Auf Stufe 9 sinkt das Tempo auf rund 55 MB/s. Liegen solche Daten in eigenen Verzeichnissen, ist eine zweite Konfiguration mit compression_level: 0 am schnellsten: Verschlüsselt wird trotzdem, und der Prozessor bleibt frei. Mit LZMA2 sollten solche Daten nie komprimiert werden.
Regel 5: Vor dem Backup aufräumen
Die größten Gewinne liegen vor dem Kompressor:
- Datenbanken als Dump sichern. Ein logischer Dump komprimiert 20 bis 40 Prozent besser als die Datenbankdatei. Ist der Dump schon mit gzip oder pigz gepackt, gehört er in eine Konfiguration mit
compression_level: 0(siehe Managed Database sichern). - Messdaten runden. Auf die tatsächlich gemessene Genauigkeit gerundete Werte komprimieren doppelt so gut und belegen am Ende ein Viertel.
- Freie Blöcke in VM-Images nullen. Images, deren Gastsystem freie Blöcke mit Nullen überschreibt (
sdelete -z,zerofree) oder perfstriman ein Image mit Discard-Unterstützung freigibt, schrumpfen um den Anteil des freien Speichers. - Kopien vermeiden. Das Fenster des Clients reicht 8 MiB zurück und endet an der Grenze einer Quelle. Projektkopien, mehrere Release-Stände oder dieselben Dateien unter zwei Pfaden speichert er mehrfach.
Regel 6: Nach dem Restore-Tempo fragen
Ein Backup wird selten geschrieben und im Ernstfall unter Zeitdruck gelesen. zstd dekomprimierte im Test mit 650 bis 910 MB/s pro Kern, xz mit 44 MB/s, bzip2 mit 19 MB/s. Wer für eine Rate von 3,0 statt 2,5 auf xz setzt, wartet im Ernstfall 15- bis 20-mal länger auf die Daten. Bei einem 2-TB-Server sind das rund 40 Minuten reine Dekompression mit zstd gegen einen halben Tag mit xz.
Die Entscheidungstabelle
| Datenart im Backup | Einstellung im Client | Erwartete Rate mit ZSTD 5 | Begründung |
|---|---|---|---|
| Logs, Text, Quellcode, Konfiguration | ZSTD, Stufe 5; bei schmaler Leitung Stufe 9 | 4 bis 8, Systemprotokolle auch über 20 | Hohe Raten, das Fenster von 8 MiB hilft |
| SQL-Dumps, unkomprimiert | ZSTD, Stufe 5 | rund 4 | Starke Wiederholungen |
| SQL-Dumps, schon mit gzip oder pigz gepackt | Stufe 0 | 1,0 | Zweite Kompression spart nichts |
| Datenbankdateien, VM-Images, ISO | ZSTD, Stufe 5 | rund 3 | Gemischter Inhalt, Nullbereiche kosten fast nichts |
| Programme, unkomprimierte Container-Layer | ZSTD, Stufe 5 | 2 bis 2,8 | Mittlere Raten, Tempo wichtiger als letzte Prozente |
| Office-Dokumente, PDF | ZSTD, Stufe 5 | 1,0 bis 1,4 | Container sind bereits Deflate-komprimiert |
| Fotos, Video, Audio, Archive | Stufe 0 in eigener Konfiguration, sonst ZSTD | 1,0 | Entropiekodierung bereits erfolgt |
| Verschlüsselte Container und Volumes | Stufe 0 in eigener Konfiguration | 1,0 | Chiffretext ist nicht komprimierbar |
| Messdaten, wissenschaftliche Arrays | vor dem Backup runden, dann ZSTD, Stufe 5 | 1,1 bis 2,2 | Überzählige Mantissenbits sind Rauschen |
Zwei Konfigurationen für einen typischen Server
Ein Server mit Anwendungsdaten, Datenbank-Dumps und einem Ordner mit Fotos braucht zwei Sicherungsaufträge. Der erste komprimiert mit ZSTD:
# /etc/lionbackup/server.yaml
lionbackup:
name: server
# … Projekt, Storage-Zone und Token wie gehabt …
files:
- /srv/app
- /srv/dumps
- /var/log
compression_method: ZSTD # ausdrücklich setzen, ohne Angabe gilt GZIP
compression_level: 5
encryption_keyfile: /etc/lionbackup/backup.pubDer zweite reicht die Fotos ohne Kompression durch:
# /etc/lionbackup/medien.yaml
lionbackup:
name: medien
# … Projekt, Storage-Zone und Token wie gehabt …
files:
- /srv/fotos
compression_level: 0 # nicht komprimieren, verschlüsselt wird trotzdem
encryption_keyfile: /etc/lionbackup/backup.pubBeide laufen nacheinander, etwa als zwei Aufrufe mit --config im selben Zeitplan.
Fazit
Kompression ist kein Schieberegler zwischen klein und schnell, sondern eine Eigenschaft der Daten, die ein Verfahren mehr oder weniger vollständig ausschöpft. Die Datenart bestimmt die Größenordnung: Logs, strukturierte Daten und Quellcode schrumpfen auf ein Sechstel bis ein Neuntel, Datenbanken auf ein Drittel bis ein Fünftel, VM-Images auf ein Drittel, Programmdateien auf weniger als die Hälfte. Was bereits entropiekodiert oder verschlüsselt ist, bleibt, wie es ist. Das Verfahren bestimmt innerhalb dieser Größenordnung die letzten 20 bis 60 Prozent und vor allem, wie viel Zeit sie kosten.
zstd hat in diesem Spannungsfeld die beste Position: die Rate von gzip bei achtfachem Tempo, die schnellste Dekompression im Test und große Fenster im selben Format. Die Gegenprobe bestätigt das für den lionbackup-Client mit zwei Einschränkungen. LZMA2 ist dort schwächer als xz und lohnt sich praktisch nie, und GZIP packt auf Rechnern mit vielen Kernen schneller, verliert aber bei Größe und Restore.
Die beiden Erkenntnisse mit der größten praktischen Wirkung stehen nicht in der Stufenliste. Erstens entscheidet bei redundanten Daten das Fenster mehr als die Stufe. Zweitens findet die wirksamste Kompression vor dem Kompressor statt: beim Dumpen von Datenbanken, beim Runden von Messdaten, beim Nullen freier Blöcke und beim Aussortieren dessen, was ohnehin nicht schrumpft.
Anhang: Messverfahren und Reproduktion
Messverfahren
Jede Messung ruft das Werkzeug als eigenen Prozess mit der Testdatei auf der Standardeingabe und der komprimierten Ausgabe in eine temporäre Datei auf, danach den Dekompressor mit dieser Datei und /dev/null als Ausgabe. Vor jeder Messung wird die Datei einmal gelesen, damit sie im Seitencache liegt. Die Zeit ist die Wanduhrzeit zwischen Prozessstart und -ende, der Speicher die maximale Resident Set Size aus wait4. Jede Kombination wurde einmal gemessen; bei Dateien unter 10 MB dominiert der Prozessstart die Zeitmessung, die Durchsatzwerte der kleinen Silesia-Dateien und des Text-PDFs sind deshalb nur Richtwerte.
Aufrufe
lz4 -1 -B7 -c lz4 -d -c
gzip -N -c gzip -d -c
zstd -N -c -q -T1 zstd -d -c -q
zstd -N --long=27 -c -q zstd -d -c -q --long=27
brotli -q N -c brotli -d -c
bzip2 -9 -c bzip2 -d -c
xz -N -c -T1 xz -d -clz4 lief mit 4-MB-Blöcken (-B7), weil die Standardeinstellung bei Eingabe über die Standardeingabe deutlich kleinere Blöcke verwendet. zstd und xz liefen mit -T1 einkernig, damit alle Verfahren denselben Kern teilen. Die synthetischen Testdaten entstehen deterministisch aus dem Seed 20261105.
Gegenprobe mit dem Client
Gemessen wurde der lionbackup-Client 0.1.35, gebaut aus dem Entwicklungsstand vom 6. November 2026 mit Go 1.27.3, klauspost/compress v1.20.3, klauspost/pgzip v1.3.0 und ulikunitz/xz v0.5.17. Die Raten stammen aus --autotune mit compression_level 1, 5 und 9. Für die Durchsätze hat ein kleines Go-Programm die Bibliotheken mit denselben Einstellungen wie der Client aufgerufen, die Daten im Arbeitsspeicher komprimiert und wie beim Restore wieder entpackt, dreimal je Messung; LZMA2 auf den Bildern lief einmal. Die Referenzwerkzeuge liefen auf denselben tar-Strömen: zstd und xz mit -T1, gzip und pigz mit Stufe 5.
Bekannte Einschränkungen
Die synthetischen Geschäftsdaten verwenden ein begrenztes Vokabular und komprimieren etwas besser als echte Kundendaten. Die HTML-Seiten und die Mailbox ziehen ihren Fließtext aus einem begrenzten Satzvorrat; Verfahren mit großem Fenster profitieren dort überdurchschnittlich, die Werte für xz -9 und zstd -19 sind deshalb nur eingeschränkt übertragbar. Die synthetischen Fotos enthalten mehr Rauschen als typische Kameraaufnahmen; die Raten für BMP und TIFF sind eine Untergrenze. Die Gegenprobe lief auf einem Notebook mit variablem Turbotakt, auf dem nebenher weitere Programme liefen; ihre Durchsätze schwanken dort um rund 20 Prozent. Ihre vier Quellen sind mit 17 bis 69 MB klein. Für die Raten genügt das, das Tempo auf großen Quellen und auf Servern mit anderen Prozessoren kann abweichen.
Versionen
Haupttest: Ubuntu 24.04.5 LTS, Intel Xeon 2,1 GHz (ein Kern), 3,9 GB RAM; gzip 1.12, bzip2 1.0.8, xz 5.4.5, zstd 1.5.5, lz4 1.9.4, brotli 1.1.0, qemu-img 8.2.2, genisoimage 1.1.11, Python 3.12 mit reportlab, python-docx, python-pptx, openpyxl, xlwt, Pillow und NumPy. Silesia-Korpus in der Fassung des GitHub-Mirrors MiloszKrajewski/SilesiaCorpus, Go-Quellcode von klauspost/compress mit Stand vom 5. November 2026. Gegenprobe: Ubuntu 26.04.1 LTS, Intel Core i5-1235U (10 Kerne, 12 Threads), 14 GB RAM; zstd 1.5.7, xz 5.8.3, gzip 1.14, pigz 2.8.
Ausprobieren
Den Client gibt es unter Downloads, den Quelltext und das Benutzerhandbuch mit allen Konfigurationsoptionen im öffentlichen Repository. Wenn Sie --autotune auf Ihren eigenen Daten laufen lassen, sehen Sie in wenigen Minuten, welche Rate Ihr Backup erreicht.