Library / SDK
google/zopfli avatar
google/zopfli

google/zopfli: very good, very slow deflate, and when that trade is worth it

Zopfli Compression Algorithm is a compression library programmed in C to perform very good, but slow, deflate or zlib compression.

3,595 stars356 forksC++Apache-2.0

At a glance

What is it?
Zopfli is a C compression library that emits deflate, gzip or zlib streams smaller than zlib's, at a large cost in CPU time. This article covers how it works, how to build and use it, and where it is the wrong tool.
Who is it for?
Adopt Zopfli when the compressed bytes are stored once and served many times, and you can afford the encoding time: static assets, published archives, firmware images. Do not adopt it for anything that compresses at request time, for streaming input, or where you need to decompress in the same process, since the README states the library can only compress.
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?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly C++, according to GitHub's language statistics.

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

Editorial analysis

What Zopfli is for, and who should reach for it

Zopfli is a compression library written in C that produces deflate, gzip or zlib streams. The README describes its purpose in one line: "very good, but slow, deflate or zlib compression". That sentence is the whole product decision. It is not a general-purpose replacement for zlib. It is a tool for the case where the compressed output is produced once and then stored or shipped, and where a smaller file is worth minutes of CPU.

The audience is narrow and identifiable. Anyone who publishes a tarball, a firmware image, a static asset bundle or an archive that will be downloaded many times is a candidate. The cost of encoding is paid once; the benefit of a smaller file is paid back on every download. A web server that gzips responses on the fly is not a candidate, because the encoder runs inside the request and the latency would be visible to the user.

The library is also usable as a building block. The repository ships a Makefile target for a shared library and a static library, so an application can link Zopfli and call it directly rather than shelling out to a binary. The README points to the entry point: the basic function to compress data is ZopfliCompress in zopfli.h, with a ZopfliOptions object controlling speed and compression, initialised by ZopfliInitOptions.

How ZopfliCompress, ZopfliOptions and the format-specific entry points fit together

The architecture is flat and easy to follow from the repository layout. All the compression code lives under src/zopfli. The Makefile lists the translation units that make up the library: blocksplitter.c, cache.c, deflate.c, gzip_container.c, hash.c, katajainen.c, lz77.c, squeeze.c, tree.c, util.c, zlib_container.c and zopfli_lib.c. That list is a fair map of the algorithm: LZ77 matching, block splitting, Huffman tree construction (katajainen.c, tree.c) and the container formats layered on top.

The public surface is small. ZopfliCompress in zopfli.h takes a parameter that selects deflate, gzip or zlib output. If you only ever need one container, the README says you can instead call ZopfliDeflate in deflate.h, ZopfliZlibCompress in zlib_container.h or ZopfliGzipCompress in gzip_container.h. Each of those creates a valid stream in memory, and the README links the relevant RFCs: RFC 1951 for deflate, RFC 1950 for zlib, RFC 1952 for gzip.

One design consequence deserves emphasis. The data flow is memory in, memory out. There is no streaming interface described, and there is no decoder at all. The README states plainly that the library can only compress, not decompress, and that existing zlib or deflate libraries can decompress the data. So Zopfli sits in front of your existing stack rather than replacing it: you compress with Zopfli, you decompress with zlib, gzip or whatever already reads deflate.

The ZopfliOptions object is where the speed-versus-size dial lives. The README says it sets parameters that affect speed and compression, and that ZopfliInitOptions places the default values in it first. It does not document the individual fields in the README text; you have to read zopfli.h for those. That is a real documentation gap for anyone tuning the library rather than just calling it.

Building zopfli and compressing a first file

The README gives a direct compiler invocation that builds the example binary from all the C sources under src/zopfli, linking the standard C math library. This is the portable path and works wherever a C compiler exists.

bash
gcc src/zopfli/*.c -O2 -W -Wall -Wextra -Wno-unused-function -ansi -pedantic -lm -o zopfli

The result is a single executable named zopfli. It is built from zopfli_bin.c, which the README describes as separate from the library and as an example program to create very well compressed gzip files.

On Linux there is also a Makefile, and the README notes it is provided only for linux. Running make builds the binary, and make libzopfli builds the shared library.

bash
make
make libzopfli

The Makefile's all target goes further: it builds zopfli, libzopfli (shared), libzopfli.a (static), and the same three for the PNG tool. The shared library rule passes -Wl,-soname,libzopfli.so.1 and writes libzopfli.so.1.0.3, matching the 1.0.3 release. For other platforms the README says to use the gcc line above instead of the Makefile.

Once the binary exists, the README does not spell out the command-line syntax, and that is worth flagging: the README documents the library API in more detail than the CLI. The example program's own usage text is the authority for flags, so check it before scripting anything.

The repository also contains go/ and rust/ directories alongside src/. The README does not describe them, so treat them as unverified until you read their contents; do not assume they mirror the C API exactly.

The limitation that decides most evaluations: it only compresses

The clearest constraint is stated in the README without hedging: this library can only compress, not decompress. If your pipeline expects one library to round-trip data, Zopfli is the wrong half of it. You will still need zlib or an equivalent decoder in the same process, which means two dependencies where you previously had one.

The second constraint is speed, which the project's own one-line description puts in the foreground. The README gives no benchmark numbers, no timing table and no guidance on how many iterations to run or what the runtime looks like on a given input size. That absence matters, because the entire adoption decision turns on it. You cannot size the cost from the documentation; you have to measure it on your own corpus.

The third constraint is build portability. The Makefile is described as Linux-only, and the shared library rule hardcodes a soname and a versioned filename. If you build on macOS or Windows, you are on the gcc-style command or on the CMakeLists.txt in the repository root, which the README does not discuss at all.

There is also a release-cadence observation. The most recent release in the repository's history is zopfli-1.0.3 from 2019-11-27, with 1.0.2 before it in 2018 and 1.0.1 in 2015. The last push to the default branch was on 2026-09-21, so the repository is not archived and is still receiving commits, but tagged releases are infrequent. If your process pins to release tags rather than to master, plan around that.

Zopfli versus zlib, brotli and the PNG optimisers

The natural comparison is zlib, because both emit deflate. The difference is not the format, it is the search. zlib's encoder makes fast greedy or lazy matching choices and stops. Zopfli, per the file list in the Makefile, carries dedicated units for block splitting (blocksplitter.c), LZ77 matching (lz77.c) and Huffman tree construction (katajainen.c, tree.c), and spends far more CPU exploring that space. The output is still deflate, so any existing decoder reads it. You are buying bytes with time, and nothing else changes downstream.

Brotli is a different format, not a slower deflate. Choosing between them is not a tuning question: a brotli stream requires a brotli decoder, a Zopfli stream does not. If your clients already speak deflate and you cannot change that, Zopfli is the option that stays inside the format.

For PNG specifically, the repository ships a second tool. The Makefile builds zopflipng from lodepng plus zopflipng_lib.cc, and there is a README.zopflipng alongside the main README. This is the Zopfli answer to PNG optimisation, and it is the reason people search for "zopfli png" rather than for the gzip binary. OptiPNG and Oxipng occupy the same space with different strategies: they re-encode PNGs and try filter and compression combinations, and they typically finish much faster. ZopfliPNG is the one that spends the most time per image. If your build step has a time budget, that difference decides the choice.

Maintenance, releases and the Apache-2.0 licence

Zopfli is licensed under Apache-2.0, and the repository carries a COPYING file plus a CONTRIBUTORS file. Apache-2.0 is a permissive licence with an explicit patent grant, which is why it is common in infrastructure code, but the practical obligations still exist: keep the licence text with redistributions and note any modified files. That is a summary of the licence family, not legal advice, and if you are shipping Zopfli inside a product you should read COPYING and the Apache-2.0 text rather than rely on a paragraph here.

The upgrade story is unusual for a project this old. The library has been at 1.0.x since 2015, and the compressed output is defined by the deflate, zlib and gzip specifications rather than by Zopfli. That means an upgrade is unlikely to change what your decoders must handle; it changes the encoder. The risk of a version bump is therefore mostly build-related: the soname in the Makefile (libzopfli.so.1) and the versioned filename (libzopfli.so.1.0.3) are the things that break packaging. If you vendor the sources and compile them into your own binary, as the gcc line does, you sidestep the shared-library versioning question entirely.

On activity: the repository is not archived, and the last push was on 2026-09-21. That is recent, but it does not by itself tell you whether the compression core is changing or whether the commits are build and packaging work. The release tags are the honest signal, and the newest is zopfli-1.0.3 from 2019-11-27.

Editorial conclusion

Adopt Zopfli when the compressed bytes are stored once and served many times, and you can afford the encoding time: static assets, published archives, firmware images. Do not adopt it for anything that compresses at request time, for streaming input, or where you need to decompress in the same process, since the README states the library can only compress. Before committing, verify two things yourself: the actual runtime on your own data, because the README gives no timing figures, and the licence terms of Apache-2.0 against how you intend to distribute the binary.

Frequently asked questions

How do I use Zopfli?

Build the example binary with the gcc command from the README, or run make on Linux, then use the resulting zopfli executable to produce gzip output. For programmatic use, call ZopfliCompress in zopfli.h after filling a ZopfliOptions object with ZopfliInitOptions.

What is the difference between Zopfli and zlib?

Both produce deflate, but Zopfli spends far more CPU searching for a smaller encoding, which the README summarises as very good but slow compression. The output is a valid deflate, zlib or gzip stream, so existing zlib-based decoders read it unchanged.

How does Zopfli compare with gzip?

gzip is a container format and a common command-line tool; Zopfli is a compressor that can emit a gzip stream, and the README describes zopfli_bin.c as an example program to create very well compressed gzip files. The trade is encoding time for a smaller file, with decompression unchanged.

Official sources

  1. google/zopfli on GitHub
  2. Issues
  3. License: Apache-2.0
  4. README
  5. Releases
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/google-zopfli.svg)](https://hysenlabs.com/projects/google-zopfli)