Evergreen Binary Compression is a feature that reduces the amount of space used on-device to store Cobalt Core binaries. The binaries are stored compressed, using the LZ4 Frame Format, and decompressed when they are loaded and run. This feature is enabled by default and required starting with Cobalt 25.
There are instructions below for disabling binary compression but this should not be done in production.
Across all reference devices tested, including Raspberry Pi 2, we have seen compression ratios just above 2.0. We therefore expect this feature to halve the space used for Cobalt binary storage when enabled for all installation slots: the system image slot and the writable slots.
Because the Cobalt Core shared library must be decompressed before it's loaded, there is necessarily some effect on startup latency and CPU memory usage. Based on our analysis across a range of devices these effects are relatively small.
For startup latency, we measured an increase in libcobalt
load time in the hundreds of milliseconds for the low-powered Raspberry Pi 2 and in the tens of milliseconds for more representative, higher-powered devices. This increase is small in the context of overall app load time.
For CPU memory usage, libcobalt.lz4
is decompressed to an in-memory ELF file before the program is loaded. We therefore expect CPU memory usage to temporarily increase by roughly the size of the uncompressed libcobalt
and then to return to a normal level once the library is loaded. And this is exactly what we've seen in our analysis.
This feature is incompatible with the Memory Mapped file feature that is controlled by the --loader_use_mmap_file
switch. With compression, we lose the required 1:1 mapping between the file and virtual memory. So, --loader_use_mmap_file
should not be set if compression is enabled for any installation slots.
Before proceeding, please note that binary compression is required starting with Cobalt 25. The feature should only be disabled for debugging or in case of emergency, after discussion with YouTube.
Separate steps are required in order for a partner to disable compression for a) the system image slot and b) (Evergreen-Full only) the 2+ writable slots on a device.
Compression for the system image slot is disabled by installing libcobalt.so
instead of libcobalt.lz4
in the read-only system image slot (i.e., SLOT_0). The open-source releases on GitHub include separate CRX packages, omitting a “compressed” suffix, that contain the pre-built and uncompressed Cobalt Core binary.
Compression for the writable slots is disabled by configuring Cobalt to launch with the --use_uncompressed_updates
flag:
$ ./loader_app --use_uncompressed_updates
This flag instructs the Cobalt Updater to request, download, and install packages containing uncompressed Cobalt Core binaries from Google Update and Google Downloads. As a result, the device ends up with libcobalt.so
instead of libcobalt.lz4
in the relevant slot after its next update.
Note that the system image slot is independent from the writable slots with respect to the compression feature: the feature can be enabled for the system image slot but disabled for the writable slots, or vice versa. However, starting with Cobalt 25 partners are required to have the feature enabled for all slots.
The compression feature is turned on by default. Once disabled, though, it can be enabled by undoing the steps required for disablement.
Compression for the system image slot is enabled by installing the compressed libcobalt.lz4
instead of libcobalt.so
in the read-only system image slot.
Compression for the writable slots is enabled by configuring Cobalt to launch without the --use_uncompressed_updates
flag. The Cobalt Updater will then be instructed to request, download, and install packages containing the compressed Cobalt Core binaries.
Note that enabling compression for the writable slots is eventual in the sense that the uncompressed Cobalt Core binaries in these slots will remain and continue to be used until newer versions of Cobalt Core are available on Google Update and Google Downloads.
The Cobalt Evergreen Overview doc describes multi-app support, where multiple Cobalt-based applications share Cobalt Core binaries (i.e., they share the same installation slot(s)). When multi-app support is used then, yes, the apps should also share compression settings.
For the system image slot, this means that either libcobalt.lz4
or libcobalt.so
is installed in the one, shared slot.
For the writable slots, this means that the loader app is either launched with --use_uncompressed_updates
set for all apps or launched without it for all apps. Otherwise, the different apps would compete with respect to whether the writable slots are upgraded to compressed or uncompressed binaries.