Skip to content
About
Main content

Choose general-purpose compression

The decision

A general-purpose codec such as or finds repeated byte patterns in any data, after whatever encoding was already applied. It trades CPU for fewer bytes, and that trade only pays when moving bytes is slower than decoding them. Should you add one, and how should it be configured?

You will end with whether to compress at all, and if so the block size, level, dictionary policy, codec and safeguards.

Work through these in order: the first can make the rest unnecessary.


Work through it

1

Decide whether to compress at all

pays only if decoding is fast enough relative to the pipe: decode speed ÷ pipe speed > ratio ÷ (ratio − 1). After good lightweight encoding the extra ratio is typically 1.2–1.5×; at 1.35, decoding must run nearly four times faster than the pipe. Over at about 80 MB/s per connection, easily true. On local at 3–7 GB/s, it needs 12–28 GB/s of decoding: several cores doing nothing else. If it does not pay: skip the pass. That is correct more often than people think.

2

Choose the block size from the access pattern

Scans: large blocks, 256 KB to 1 MB. : small blocks, 4–16 KB. This matters more than the codec: a 100-byte lookup from a 256 KB block reads about 2,600 times the bytes it needs, and one corrupted bit destroys every record in the block.

3

Choose the level from reads per write

The level only controls how hard the encoder searches. Read many times: a high level, applied when data is compacted, not at ingest. Read rarely: level 1–3.

4

Small, similar records: a trained dictionary

If blocks are small and records share structure: train a dictionary on sample data, which brings back ratio a small block cannot find on its own. Treat it as a permanent, versioned artifact, not a setting: record its ID in each block and keep every old version forever, because a missing dictionary means unreadable data.

5

Choose the codec last

It is nearly always ZSTD; LZ4 if decompression speed is the limit; only if a protocol requires it.

6

Checksum every block

Always. It is nearly free, and it detects the corruption that compression magnifies: a bad block is reported and repaired from a replica instead of returning noise.

7

Compress, then encrypt; never the reverse

Good encryption output looks random, so it cannot be compressed: if compressing after encryption achieves anything, the cipher is broken. In the right order a small leak remains: the length of the encrypted data reveals the compressed length. For data at rest this rarely matters, except with per-column encryption plus per-column compression, where the file exposes each column's compressed size.