Open-source project
richox/orz avatar
richox/orz

orz is a ROLZ compressor written for speed rather than ratio

a high performance, general purpose data compressor written in the crab-lang

815 stars50 forksRustApache-2.0

At a glance

What is it?
orz is a general purpose compressor built on the ROLZ algorithm with a Move-to-Front transformer and a static Huffman coder on top, packaged as a Rust crate. Its claim is a favourable ratio and speed trade-off, and the enwik8 table in the README is the place to judge it.
Who is it for?
orz suits someone who compresses a lot of data and cares more about how long the encoder takes than about the last few percent of ratio, since the enwik8 numbers in the README show it encoding in seconds where xz and zstd at high levels take tens of seconds. It is the wrong choice for a format where you want the smallest possible output, because zstd at level 19 beats it on both size and decode time.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

ROLZ with a transformer and a static Huffman stage

orz is described as an optimized ROLZ, reduced offset Lempel-Ziv, general purpose data compressor. The README explains the pipeline in a single sentence: input data is encoded as ROLZ matches, which are reduced offsets and match lengths, plus 2-byte words and single bytes, and then all the encoded symbols are processed with a symbol ranking transformer, also known as Move-to-Front, followed by a static Huffman coder.

Each stage does a different job. The Lempel-Ziv part finds repetitions and replaces them with a distance and a length, and the reduced offset variant shrinks the distance alphabet, which is what makes the match encoding cheaper than plain LZ. The Move-to-Front stage then reorders the symbol stream so that recently used symbols get short codes, which is where a lot of the practical win comes from, since a static Huffman coder has no way to adapt to a shifting distribution on its own.

That static final stage is a deliberate trade. A static Huffman table is cheaper to decode and can be shipped alongside the data, but it is fitted to one input, so the coder has to be built for that stream rather than reused across many.

The crate is Apache-2.0 or MIT licensed, and the project has no GitHub releases.

Building and installing the binary

The README is direct about the build: clone the repo and run cargo build --release to have an executable orz binary.

The install route goes through cargo as well, pinned to a specific tag:

bash
    cargo install orz --git https://github.com/richox/orz --tag v1.6.2

Pinning the tag rather than tracking the default branch is the right call for a compressor, because a change in the entropy coder changes the output format and a mismatched encoder and decoder loses data rather than producing a warning.

The manifest describes a package named orz at version 1.6.1, edition 2024, authored by Zhang Li. The dependency list is short: bitfield-struct at 0.12.1, clap at 4.6.0 with the derive feature, and unchecked-index at 0.2.2. Clap with derive is what gives the command line its subcommands and help text, and the crate type is declared as rlib, staticlib and cdylib, so the same crate can be linked into other Rust code or built as a C compatible library.

The release profile is tuned hard. codegen-units is 1, lto is on, opt-level is 3, incremental is off, debug assertions are off and overflow checks are off. For a compressor that does a lot of arithmetic in hot loops, that is the configuration you would expect, and it is also why a debug build tells you little about the encoder's real speed.

Two subcommands and a help page

The command line is two verbs. Compression takes the source file and the compressed file:

bash
    orz encode <source-file-input> <compressed-file-output>

and decompression takes the compressed file and the source file:

bash
    orz decode <compressed-file-input> <source-file-output>

For anything beyond that, the README points at orz --help.

The two file arguments in both directions are worth noting, because it means the tool has no standard input or output mode described here. Every invocation names two paths. For a pipeline where you want to compress a stream coming out of one program and feed it into another, you would be using temporary files, or checking whether the help output offers something the README does not mention. The README does not document such a mode, so a reader who needs it should check the help page rather than assume it exists.

There is also a benchmark-tool directory at the repository root and a test directory, and the release profile in the manifest is the same one those tools are built with.

The enwik8 table, read carefully

The README benchmarks 100MB of the Large Text Compression Benchmark, enwik8, and publishes a table with compressed size, encode time and decode time for a range of tools. The claim the README makes is that, benefited from the ROLZ algorithm, orz compresses much faster than many other LZ-based compressors with the same compression ratio, and that decompression speed is still very acceptable.

The orz rows show three levels. At level 2 the compressed size is 26,892,825 with an encode time of 3.360s and a decode time of 0.578s. At level 1 the size is 27,217,825, encoding in 2.503s and decoding in 0.588s. At level 0 the size is 27,898,433, encoding in 1.773s and decoding in 0.603s.

The comparisons are informative. xz at level 6 produces a smaller file, 26,665,156, but takes 44.936s to encode against 3.360s, and its decode is 0.812s against 0.578s. zstd at level 19 is close in size at 26,944,223 but takes 45.985s to encode, and it decodes in 0.085s, which is far faster than orz.

So the picture is not that orz wins everywhere. It wins on encode speed, roughly an order of magnitude over the high compression settings of xz and zstd, and it sits in the middle on decode. Against zstd at level 10 it is comparable in size, 27,898,433 against 30,697,508 at level 0 of orz, and much slower to encode.

The README also says the latest enwik8 result is in the GitHub Actions workflow, so the table in the README is a snapshot rather than a live figure.

Where a general purpose compressor is the wrong choice

A general purpose compressor is by definition not the best answer to a specific problem, and the enwik8 table makes the specific cases visible.

If you want the smallest possible output, zstd at level 19 wins against every orz level, and it decodes six times faster than orz does, at the cost of an encode that takes more than twenty times as long. If you want fast decompression on the reading side, zstd at level 10 decodes in 0.082s and lzfse in 0.080s, against 0.578s for orz.

The case where orz is clearly ahead is an encode-heavy workload with a large corpus. Compressing 100MB in under four seconds, or in under two at level 0, with an output only a few percent larger than the best settings of the alternatives, is a good trade when the encode happens on every build and the decode happens once.

The obvious comparison outside this table is a specialised format, and the general rule applies: if your data is one specific thing, such as images, video, or already compressed archives, a format built for that beats a general purpose codec, and orz will not change that.

One more practical limitation comes from the project itself. The README says orz is completely implemented in the crab-lang, while the repository is a Cargo project whose manifest is edition 2024 with Rust dependencies, and whose primary language is listed as Rust. Whatever the crab-lang is, the code you can read and build here is a Rust crate, and that is what you are adopting.

Licensing, releases and the state of the repository

The repository carries both LICENSE-APACHE and LICENSE-MIT files, and the manifest header states the dual licence explicitly, giving the Apache 2.0 or MIT choice at your option. The README badges for both licences point at those two files. That is the standard Rust ecosystem pattern, and it means the licence question is settled for most uses; any specific compliance question belongs with your own counsel.

The manifest also has a comment block that reads like a deliberate notice about the licence file itself, saying the file may not be copied, modified or distributed except according to those terms.

On releases, the repository has no GitHub releases, even though the install instructions reference a tag, v1.6.2, while the manifest version reads 1.6.1. That gap is small but it is the kind of detail that matters for a tool whose output format has to match between encoder and decoder. The last push was on 2026-04-15, and the repository is not archived, so the branch is moving without a tagged release stream.

For anyone pinning orz in a pipeline, that means pinning a specific commit or a specific tag and testing the round trip, rather than tracking the default branch.

Editorial conclusion

orz suits someone who compresses a lot of data and cares more about how long the encoder takes than about the last few percent of ratio, since the enwik8 numbers in the README show it encoding in seconds where xz and zstd at high levels take tens of seconds. It is the wrong choice for a format where you want the smallest possible output, because zstd at level 19 beats it on both size and decode time. Before adopting it, build it with cargo build --release, run orz --help, and compare the compressed sizes and timings on your own data rather than on the enwik8 figures.

Frequently asked questions

How do I install orz?

Clone the repository and run cargo build --release for a local binary, or install it with cargo install orz --git https://github.com/richox/orz --tag v1.6.2, which pins the install to a specific tag rather than the default branch.

How do I compress and decompress a file with orz?

The compressor takes two file arguments, orz encode <source-file-input> <compressed-file-output>, and the decompressor mirrors it with orz decode <compressed-file-input> <source-file-output>. For anything else, orz --help documents the remaining options.

How does orz compare with xz and zstd on the enwik8 benchmark?

On 100MB of enwik8, orz at level 2 encodes 26,892,825 bytes in 3.360s while xz -6 encodes a smaller 26,665,156 bytes in 44.936s, and zstd -19 encodes 26,944,223 bytes in 45.985s but decodes in 0.085s against orz's 0.578s.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. README
  4. richox/orz on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/richox-orz.svg)](https://hysenlabs.com/projects/richox-orz)

Was this useful?