The codec
Underneath the GPU work, Glyd is a lossless compression library and command line, written in Rust with a C ABI, for the workloads where storage and read CPU decide the bill: object storage, data lakes, logs and telemetry, backups and versioned exports, RPC payloads, caches. It is a drop-in alternative to LZ4, Snappy and zstd, and does two things they do not: it turns record-shaped data (logs, dumps, CSV, JSON lines) into typed columns before compressing (-r), and it compresses a new version of an object against the old one (--base). Install it with Homebrew, cargo or a wheel (getting started).
Levels
| Level | Use it for | How it works |
|---|---|---|
--turbo (-t) |
data read far more often than written: caches, assets, KV-cache paging | v6 format, minimum match 10: fewest tokens, one 32-byte copy a token |
| default | the LZ4 and Snappy slot, with a better ratio and faster reads | v6 format, an LZAV-class finder, minimum match 7 |
--fast (-1) |
LZ4-class compression speed | v6 format, an LZ4-class finder, minimum match 5 |
--max (-9) |
the zstd -3 slot: fewer bytes, 3 to 7 times faster reads on a server | v9 format: 8-way interleaved Huffman literals, tANS sequences with repeat offsets, a double-fast parse over an 8 MB window |
--max --long (-L) |
events, logs, anything that repeats itself across a file | the same, with a 128 MB long-distance matcher run once before the parse |
--max --dense (-D) |
objects written once and read rarely | --long in 128 MB units parsed in stripes on all cores |
--ultra (-19) |
write once, read many: datasets, release assets | v9 format on an optimal parse, every position priced in the coder’s own bits |
--cold (-C) |
stored for years, read rarely: archives, the last copy | context mixing: every bit predicted from eleven contexts, 1 to 1.3 MB/s a core each way |
All levels write one container, and the decoder reads any mix; the level and mode are in the stream.
Modes
- Record mode,
-r, for logs of any shape, SQL dumps, CSV and JSON lines: it detects the shape, turns each field, key path or template slot into a typed stream (integer, decimal and date-time deltas, dictionaries, text), compresses those with the level and rebuilds the bytes exactly. - Base mode,
--base, for versions: nightly dumps, snapshots, images, source trees. Each 32 MB of the new version is parsed with the region of the old one that holds its content as history; decoding needs the same base.
glyd --max events.json -o events.glyd # the zstd -3 slot: fewer bytes, 3-7x faster reads
glyd --max -r access.log -o access.glyd # record mode: logs, dumps, CSV, JSON lines as columns
glyd --ultra -r dump.sql -o dump.glyd # fewest bytes from a parse; slow to write
glyd --cold -r dump.sql -o dump.glyd # fewest bytes of all; 1 MB/s per core each way
glyd --base dump-mon.sql dump-tue.sql -o tue.glyd # base mode: Tuesday's dump against Monday's
glyd -d --base dump-mon.sql tue.glyd -o tue.sql # decoding a base-mode file needs the base
glyd -d events.glyd -o events.json # the level and mode are in the stream
glyd -b bigfile # benchmark every level on your data
The store
glyd-store keeps objects compressed across a bucket: an object is stored as a delta against the stored object it most resembles, found by fingerprints, when that pays, and alone otherwise; chains are at most four long. The objects’ bytes go to a directory or to S3 (or any S3-compatible service); every object reads back byte-exact.
glyd-store bucket/ --put mon.tar tue.tar wed.tar # the store finds each object's base itself
glyd-store bucket/ --get 2 -o wed.tar # also --find NAME, --delete ID, --rebase ID, --compact, --verify, --stats
glyd-store meta/ --s3 s3://bucket/prefix --put wed.tar # objects in S3
glyd-store --audit s3://bucket/prefix # what the store would save there, from a sample
The store is under the Business Source License 1.1 (licenses).
From code
Rust:
let mut out = Vec::new();
glyd::compress_parallel_into_max(&input, &mut out); // or compress_into_max, _ultra, _cold, compress_into (default)
let back = glyd::decompress_parallel(&out)?; // any level, any block mix
glyd::compress_records_into_max(&log, &mut out); // record mode (-r); decompress() reads it
glyd::compress_with_base(&old, &new, &mut out, false);// base mode; decompress_with_base(&old, &out)
Python (bindings/python):
import glyd
c = glyd.compress(data, records=True) # decompress(c); pack(objects); Store("bucket/").put(name, data)
C, C++ and Go (cgo over the same header, bindings/go): link libglyd and include include/glyd.h.
size_t cap = glyd_max_compressed_len(n);
int64_t clen = glyd_compress_max_parallel(src, n, dst, cap); // or glyd_compress / _parallel
int64_t dlen = glyd_decompress_parallel(dst, clen, out, n);
The formats are specified in docs/spec.md; every release decodes every earlier format. The codec’s benchmarks, against zstd, LZ4, xz and brotli on public data, are in the repository’s README.