Zudoku
Tutorials

Rootfs Compression

Compressing the root file system represents using an algorithm like gzip, zstd, etc. to reduce the size of the rootfs on disk. This has the added benefit of reducing the time it takes to push the image to the Unikraft Cloud platform, as you transfer less data. It also means that the size on disk on the host side reduces, which can be beneficial when dealing with many images or large images. This size can drop depending on the contents of the rootfs and the compression algorithm used. For example, text files often compress by up to 90% and more, whilst already compressed files like images or videos don't compress well at all.

Getting started

The Unikraft Platform supports compressed EROFS rootfses, but it's highly recommended to use uncompressed ones if size allows. The kernel decompresses the data at runtime, which makes file access slower across the board. That's why the first attempt at using the platform should always be with uncompressed rootfses.

Of the two rootfs formats, only EROFS supports compression. Unikraft Cloud doesn't support a compressed CPIO rootfs. EROFS does per-block compression, which means that the system decompresses only the blocks that it reads. EROFS supports most compression algorithms, but the recommended ones are those that have fast decompression speeds like lz4hc.

As presented in the rootfs formats tutorial and in the FAQ, the performance characteristics of the two formats differ. With a compressed EROFS rootfs, boot times change less, and memory usage stays low, because the system decompresses only the blocks that it reads. Compression has a downside that Direct Access (DAX) isn't possible when using compression, as the host side can't map a compressed image into guest memory. This caveat results in having to load the entire compressed rootfs into guest memory, increasing memory usage by at least the size of the compressed rootfs. Still, if many files aren't accessed in boot, the cold boot time might decrease compared to an uncompressed EROFS rootfs.

Packaging a compressed rootfs

The unikraft CLI doesn't support compressing rootfses. This choice is deliberate, as the performance downsides aren't worth it most of the time. The unikraft CLI supports deploying pre-compressed EROFS rootfses.

As a study case, this tutorial uses this node image, which has a big rootfs size. A full guide on using this image is available here.

To package a compressed EROFS rootfs, you need to use the mkfs.erofs tool before packaging it with the CLI. To do this you will also have to first export the image built from the Dockerfile into a tar archive:

TerminalCode
docker build -o type=tar,dest=rootfs.tar -t node-playwright-chromium -f Dockerfile .

You can then use the resulting tar archive to create a compressed EROFS rootfs using the following command. Note that you can change the compression algorithm and level by modifying the -z option. In this example the level is 9 (maximum) and the algorithm is lz4hc (high compression lz4):

TerminalCode
mkfs.erofs --all-root -b 4096 -d2 -E noinline_data -z lz4hc,9 rootfs.erofs --tar=rootfs rootfs.tar

Finally, you can package and deploy the compressed EROFS rootfs using the CLI:

TerminalCode
# first, modify the Kraftfile to use the compressed EROFS rootfs: # ... # rootfs: # source: ./rootfs.erofs # ... # build and deploy the image unikraft build . --output <my-org>/node-playwright-chromium:erofs-compressed unikraft run --metro fra \ --scale-to-zero policy=on \ -p 443:8080/http+tls \ -m 600M \ --image <my-org>/node-playwright-chromium:erofs-compressed

Performance impact

You can see below the same node image packaged and deployed three times: as an uncompressed CPIO rootfs, and as an EROFS rootfs with and without compression. You can view the results in the table below, which show the image size, boot times, and minimum memory requirements for each case.

To check the image size, you can list your images:

TerminalCode
unikraft images list
rootfs TypeCompressionImage SizeBoot TimeInstance Memory Required
CPIONo916 MiB1152.08 ms2700 MiB
EROFSNo924 MiB155.39 ms1000 MiB
EROFSYes (lz4hc)542 MiB122.10 ms600 MiB

The image sizes reported in the table also contain the base-compat kernel layer, which is around 36MiB. The instance memory required is the minimum memory required to boot the instance, and respond to a simple curl request.

EROFS performs better in both compressed and uncompressed forms, compared to CPIO. The compressed EROFS rootfs boots even faster than the uncompressed one. This is likely due to the reduced amount of data that the system reads from disk, resulting in faster access times despite the decompression overhead. This only happens in the cold boot scenario. In warm boots, the uncompressed EROFS rootfs tops the charts as the system needs no decompression at all, and wakeups happen faster.

When it comes to memory usage, you can see that the CPIO image requires a lot more memory to boot. This is because the system must unpack the full archive into memory before it can use it. Unikraft Cloud reclaims that memory after boot, but the initial memory overhead is still higher than with EROFS. With EROFS, you don't see this limitation.

For BYOC or on-prem deployments, Unikraft Cloud offers the option to share the same read-only initrd between instances when using EROFS images. This has the added benefit that Unikraft Cloud loads the initrd into host memory only once as read-only. Instances only map the pages they need, which reduces memory usage and boot times even further. Upon writing, the system performs copy-on-write, meaning that it copies only the modified pages into the instance's memory. In this case, the boot time differences between compressed and uncompressed EROFS rootfses are negligible. There might still be a difference when handling page faults, when accessing parts of the rootfs for the first time.

Conclusion

As a rule of thumb, use uncompressed rootfses whenever possible and try to always use EROFS over CPIO for better performance. If limited by size constraints, try using compressed EROFS rootfses with a fast decompression algorithm like lz4hc.

Learn more

Last modified on