Engineering / August 14, 2026
81 cpak images, 41 GiB lighter
I ran a full diagnosis across all 81 cpak images in the official catalogue and what I found was hard to ignore: on a machine with no cached layers, downloading them meant transferring 69.2 GiB, while after rebuilding the base images and every affected package the same catalogue is down to 27.8 GiB. That is a 59.8% reduction, with 4.3 GiB less unique data stored across those images.
Applications measured
81
Download reduction
59.8%
Unique data removed
4.3 GiB
Where the space was going
To understand where that space went, we first need to look at how a cpak image is built. cpak uses OCI images, which can be thought of as a stack of immutable snapshots called layers. Each build step adds a layer; deleting a file in a later one hides it from the final filesystem, but does not rewrite the snapshot where that file was created.
This is where I found the first problem. Some packages downloaded an installer in one layer, unpacked it, then deleted it in the next one. The archive looked gone inside the application, but the layer containing it still had to be downloaded at every new installation.
I moved the download and extraction work into separate build stages, then copied only the finished application into the image people install. Installers and temporary build files now stay outside the final image instead of being hidden in an earlier layer.
First download, no cache
All 81 applications
59.8% smaller
Cleaning the base images
The base images had their own share of unused data: package caches, indexes, manuals, development documentation and distribution reports. None of these files helps an application run, so I changed the build process to discard them before a layer is created rather than trying to delete them afterwards.
Runtime data remains untouched, so icons, translations, settings schemas, certificates, fonts, MIME definitions and licences continue to work as before. Package maintainers also keep the same build commands because the cleanup happens inside the base itself.
A base for what the application actually uses
Some bases had grown large enough to cover almost any desktop application, which meant a GTK 3 program could also receive GTK 4, libadwaita, WebKitGTK and a complete 32-bit graphics stack it never used.
I split them by toolkit and graphics requirements, so each application receives the base it actually needs. The shared parts still use identical OCI layers, which means cpak downloads a common layer once and reuses it for every application built on top of it.
When every shared layer is counted only once, the 81 applications fall from 17.5 GiB to 13.2 GiB of unique registry data. In other words, the catalogue now stores 4.3 GiB less before cpak starts deduplicating individual files on the machine.
Shared layers counted once
Registry storage for all 81 applications
24.5% smaller
Then I measured the result on disk
The registry comparison tells us how much data is downloaded, but not how much space it will occupy after installation. Once OCI has shared identical layers, cpak's FVS storage engine goes deeper and shares equal file blocks even when they arrived through different layers.
To measure the final result, I imported Chrome, Firefox and Telegram into two empty cpak stores with cpak v2.3.1, once with the previous images and once with the rebuilt ones.
The previous images occupied 3.19 GiB after deduplication. The rebuilt images occupy 1.56 GiB, a reduction of 51.2%. The number of stored content blocks also fell from 21,694 to 10,807.
Installed on disk
Chrome, Firefox and Telegram
51.2% smaller
I also found space the migration was not releasing
The diagnosis exposed a separate bug in the move to FVS storage. When a layer had already been imported into FVS but its old expanded copy was still present, both used the same digest and the garbage collector treated both as active. The old DaBaDee data could remain hard-linked to that expanded layer, so removing its directory alone did not reclaim the space.
cpak now checks whether the referenced FVS layer is available and keeps it as the
authoritative copy. The duplicate expanded layer can then be removed and the legacy
object store can release its remaining data. Existing installations can recover that
space with cpak gc --apply; reinstalling the applications is not required.
The same work on SDKs and Bottles
The catalogue also contains 14 official SDK images, so I applied the same work to their development bases. Their combined download falls from 5.2 GiB to 4.1 GiB, while unique OCI data falls from 1.94 GiB to 1.71 GiB. Qt and Vulkan no longer inherit the complete multilib SDK, while Vala now uses the GTK 4 SDK instead of the old all-toolkit image.
Go and Node received the same cleanup while keeping their amd64 and arm64 builds. Packages built with those SDKs now start from the smaller base without requiring any recipe changes.
Bottles is built from its own repository, so I measured it separately. Rebuilding its cpak against the new Wine base reduced the official image from 1054.4 MiB to 568.3 MiB without changing Bottles or removing any declared dependency.
How I measured these numbers
Each number comes from the published Linux amd64 manifests on GHCR rather than an estimate. The total download adds every compressed layer used by all 81 applications, while the unique size groups layers by their SHA-256 digest and counts shared data only once. Previous measurements use immutable manifests or commit tags and the new ones use the images produced after the rebuild.
The complete 81-image comparison measures downloads and registry storage before local FVS deduplication. The separate Chrome, Firefox and Telegram sample measures the space allocated on disk after FVS has done its work. Every new image completed its GitHub Actions build before entering either result.