Skip to main content
Hayate compresses every transfer with Zstd level 1 by default. Compression runs on the sender before encryption, so the data travelling over the wire is both smaller and fully encrypted. For most file types — source code, logs, plain text, uncompressed archives, and raw data — this reduces transfer time noticeably even on a gigabit LAN. For files that are already compressed, Hayate detects the format from the file extension and skips Zstd entirely, so you never waste CPU cycles trying to compress data that won’t shrink.

Default Behavior

Zstd level 1 compression is on by default for all transfers. You do not need to pass any flag to enable it. Each payload frame is individually compressed and then encrypted before being sent, so the receiver always gets authenticated, decryptable data regardless of the compression state of any given frame. Compression and encryption are coordinated at the frame level using a single flag byte prepended to each decrypted frame:
  • FRAME_RAW (0x00) — the frame payload is uncompressed.
  • FRAME_ZSTD (0x01) — the frame payload was compressed with Zstd before encryption.
This means that within a single transfer, some frames can be compressed and others raw — Hayate makes the decision per-frame based on what it knows about the file type.

Smart Skip: Pre-Compressed Formats

Trying to Zstd-compress an already-compressed file is a waste of CPU and occasionally makes the output larger. Hayate detects pre-compressed formats by file extension and sends them raw (with FRAME_RAW frames) instead. The following extensions are automatically skipped:

Archive formats

.zip .gz .bz2 .xz .zst .7z .rar .br

Video formats

.mp4 .mkv .mov .m4v .webm

Audio formats

.flac .opus

Image formats

.jpg .png .webp
For any extension not on this list, Zstd level 1 compression is applied.

Why Zstd Level 1?

Zstd level 1 is tuned for throughput, not maximum compression ratio. At level 1, Zstd typically processes data faster than a gigabit network link can move it, which means compression adds negligible latency to your transfer while still delivering meaningful size reduction for compressible data. For a typical mix of source code, logs, and configuration files you can expect 2–4× size reduction. For already-dense binary formats (compiled objects, ML model weights), the reduction is smaller, but the CPU cost is also lower. Higher Zstd levels (2–22) trade more CPU time for better ratios. Hayate uses level 1 because the goal is wire-speed transfers — not optimal compression ratios.

Compression and Encryption Order

Hayate always compresses data before encrypting it. This ordering matters: encryption produces output that is statistically indistinguishable from random noise, which means it is incompressible. If you reversed the order and encrypted first, Zstd would find nothing to compress. By compressing first, Hayate gets the full benefit of Zstd’s dictionary-based algorithms on the original data before it is encrypted.

Controlling Compression

The -z / --compress flag accepts true (default) or false. When --compress=false is set, all frames are sent as FRAME_RAW regardless of file extension.

Compression in the Rust Library

When embedding Hayate in your own application, control compression with the .compress(bool) builder method on HayateSender:
Disable compression when you are sending files that are already compressed (.zip, .mp4, .tar.gz, model weights, encrypted containers) or when you need to minimise CPU usage on constrained hardware. For everything else — source trees, log archives, CSV dumps, database exports, .tar files — leave compression on and let Zstd level 1 do its job.
Hayate uses Zstd with its default dictionary at level 1. No custom training data or pre-built dictionary is loaded at runtime. This keeps the binary small and startup instant while still delivering the full speed advantage of Zstd’s core algorithm. If your workload involves highly repetitive data and you need better compression ratios, consider pre-processing with a higher Zstd level outside of Hayate before sending the already-compressed archive.