Sizing the super
partition correctly is important for device updateability. The size
directly impacts how many updates a device can take and how many users can successfully take those
updates.
There are a few important variables to consider. The first is factory size, which is the size of all dynamic partitions when the device is first flashed. The second is the growth rate, which is the percentage the OS size increases over the entire updatable life of the device.
Additionally, Virtual A/B devices can use space on /data
during an update, and this
must be considered when sizing super
. If too much space is needed on
/data
, then some users are unable (or unwilling) to take the update. However, if it's
known that most users have some percentage of space free, then devices can comfortably subtract
that space from super
. Or, devices can guarantee that /data
is never
needed, simply by making super
large enough.
Below are some models to help guide super
partition sizing based on these
variables.
Rely on /data
Virtual A/B encourages shrinking super
to allow increasing the size of
/data
. Some of that space is needed during an update. To understand the impact on
updateability, it's essential to know what percentage of devices are likely to have that amount of
space free over time. Figuring out this number is highly dependent on the device's hardware and
users' behavior of that device. In the examples below, this number is referred to as
AllowedUserdataUse
.
Without compression
Without compression, a full OTA needs a snapshot roughly the same size as the OS, so that must be
taken into account when sizing super
:
FinalDessertSize = FactorySize + (FactorySize * ExpectedGrowth) Super = Max(FinalDessertUpdate, FinalDessertSize * 2 - AllowedUserdataUse)
For example, consider a Virtual A/B device with a factory size of 4 GB, expected growth of
50%, and knowledge that almost all users have 1 GB free (or are willing to free up to 1 GB
of space for an update). For this device, super
can be sized like so:
FinalDessertSize = 4GB + (4GB * 0.5) = 6GB Super = Max(6GB, 6GB * 2 - 1GB) = Max(6GB, 11GB)
Thus, this device should have an 11 GB super
partition.
With compression
With compression, a full OTA needs a snapshot roughly 70% of the size of the OS:
FinalDessertSize = FactorySize + (FactorySize * ExpectedGrowth) FinalOTASnapshotSize = FinalDessertSize * 0.7 Super = Max(FinalDessertUpdate, FinalDessertSize + FinalOTASnapshotSize - AllowedUserdataUse)
For example, consider a device configured with Virtual A/B compression, with a factory size of
4GB, expected growth of 50%, and knowledge that almost all users have 1 GB free (or are willing
to free up to 1 GB of space for an update). For this device, super
can be sized
like so:
FinalDessertSize = 4GB + (4GB * 0.5) = 6GB FinalOTASnapshotSize = 6GB * 0.7 = 4.2GB Super = Max(6GB, 6GB + 4.2GB - 1GB) = Max(6GB, 9.2GB) = 9.2GB
Thus, this device should have a 9.2 GB super
partition.
Without relying on /data
If you want to have OTAs that never require snapshot space on /data
, then sizing
super
is straightforward.
Without compression
For a Virtual A/B device without compression, or a normal A/B device:
FinalDessertSize = FactorySize + (FactorySize * ExpectedGrowth) Super = FinalDessertSize * 2
For example, consider a Virtual A/B device with a factory size of 4 GB and expected growth
of 50%. To ensure this device never uses /data
for OTA snapshots, its calculation would
look like:
FinalDessertSize = 4GB + (4GB * 0.5) = 6GB Super = FinalDessertSize * 2 = 12GB
Thus, this device should have a 12 GB super
partition.
With compression
For a Virtual A/B device with compression:
FinalDessertSize = FactorySize + (FactorySize * ExpectedGrowth) FinalOTASnapshotSize = FinalDessertSize * 0.7 Super = FinalDessertSize + FinalOTASnapshotSize
For example, consider a Virtual A/B compression device with a factory size of 4 GB and
expected growth of 50%. To ensure this device never uses /data
for OTA snapshots, its
calculation would look like:
FinalDessertSize = 4GB + (4GB * 0.5) = 6GB FinalOTASnapshotSize = 6GB * 0.7 = 4.2GB Super = 6GB + 4.2GB = 10.2GB
Thus, this device should have a 10.2 GB super
partition.
Caveats
It might be tempting to observe that if the factory size is 4 GB, and the final update is
5 GB, then super
needs to be 9 GB, rather than 10 GB. However, if the
first update and final update are both 5 GB, then space in super
might be
insufficient for the final update. The formulas above assume that partition growth could happen at
any time. The space needed to apply the final update might be the same as required to apply the first
update.
Note that compression ratios are an estimate. An OS image might compress better or worse depending on its contents. If using a compressed file system such as EROFS, the additional compression from Virtual A/B has diminishing returns. In this case it's better to use one of the uncompressed formulas as a guideline.
Calculate the size
To find the value of FinalDessertSize
in the above examples, add the sizes of all
dynamic partitions together. The AOSP dynamic partition images are:
system.img
vendor.img
product.img
system_ext.img
vendor_dlkm.img
system_dlkm.img
Make sure to calculate the size based on unsparsed images. When building Android
12 or lower, images are sparsed by default, and can be unsparsed with
simg2img
.
It's also possible to calculate partition sizes from an OTA package. Doing so also estimates the Virtual A/B snapshot size for each partition:
python3 system/update_engine/scripts/payload_info.py path/to/ota-package.zip
Or, you can use the OTA Analysis Tool. This tool doesn't upload any files and analyzes OTA packages locally.
To find the value of ExpectedGrowth
, use a previously released device. Use the
earliest and most recent super
image to calculate the growth.