Delta patches with Play Asset Delivery

How do we optimize our project for delta patching using Play Asset Delivery on Android?

The Google overview page for Play Asset Delivery (PAD) says that PAD supports delta patching. As far as I can tell, no additional information is provided about the implementation.

The Unity documentation for PAD does not provide any information about delta patching, or how to organize/optimize the project for delta patching.

We want to avoid the situation where changing any application content causes all of the Asset Packs to get rebuilt and requires the end user to re-download all of the application content with each update.

Is this possible using Generated Asset Packs or only using Custom Asset Packs? Is it possible with all delivery modes or only certain delivery modes? What settings and workflow should we use? Is there a way to check the delta size without publishing the new build to Google Play?

When I test with the following configuration on Google Play’s Internal Testing track, delta patching does not appear to work correctly:

  • Split Application Binary enabled
  • Default PAD settings (Unity generates one install-time asset pack “UnityDataAssetPack”)
  • Asset Bundle Compression: LZ4
  • Internal Bundle Id Mode: Group GUID
  • Bundle Naming Mode: Use Hash of Filename

To test, I made an AAB build (let’s call it Build 1), uploaded it to Google Play, waited for it to show up, and installed it on my phone. The build was 380 MB. Then I made some changes to the files in 1 of our 18 Addressables groups and made a new build (let’s call it Build 2) which was also 380 MB.

I made a copy of each AAB and changed the extension of the copy to .zip. Using Windows Explorer, I browsed through the Asset Bundles in the “UnityDataAssetPack” folder of each Zip, and compared the files by right-clicking each file and choosing “Properties”.

As expected, the file sizes and CRC-32 checksums for most of the Asset Bundles are exactly the same in both Build 1 and Build 2. For the one Addressable Group where I made changes (a 30 MB bundle), the CRC-32 had changed. So most of the files were identical from Build 1 to Build 2, and the update size in theory should have been around 30 MB.

I uploaded Build 2 to Google Play, waited for it to show up, and checked the update size. Google Play showed an update size of 380 MB. I downloaded the update, and the progress meter showed that I downloaded 380 MB.

tl;dr
Although most of the Asset Bundle files have not changed at all between builds, Google Play appears not to use delta patching and still downloads all of the application content. It’s possible that this is a quirk of the Internal Testing track, but if that’s documented somewhere, I can’t find it. Or maybe delta patching only works at the Asset Pack level and not for the individual files within the Asset Pack, which would mean that Unity’s default approach of putting all of the assets into one Asset Pack means that we just don’t get delta patching.

Ahah! Finally figured this out!

At least for the Internal Testing track, Google does not generate a delta update until after the first time that the update is installed on a device. This means that the first phone to download the update will have to re-download all of the application content.

  1. Installed Build 2 onto Phone A and Phone B
  2. Made some trivial changes to files in one Addressables group and compiled Build 3
  3. Uploaded Build 3 to Google Play. Both phones showed that the update size was 380 MB.
  4. (Waited 16 hours before installing the update to see if update size changed. It did not.)
  5. Downloaded Build 3 to Phone A.
  6. Waited a few hours.
  7. Checked the update size on Phone B. The update size now showed as ~4 MB.

So, for at least Internal Testing, you need to download the update once before Google will generate an optimized delta update. Presumably this is to save some CPU time in case no one ever installs the build. I haven’t tested on a Closed Testing or Release track, so I don’t know if the same rule applies there.

Ideally, you should have multiple Android phones to test with, but if you only have one phone, you can try the following:

  1. Upload the new build to Internal Testing.
  2. Install the new build on your phone through the Google Play app.
  3. Wait for a while for Google to generate a delta update (not sure how long, possibly several hours).
  4. Use Internal App Sharing to download the previous build.
  5. Look at the app in Google Play again. Since you just installed an older build, you should see the “Update” button again. Check the application details to find the update size.