◉ANTIGRAVITY LABJP
Articles/App Development
▣ App Development/2026-07-03Intermediate

Catching Download Size Regressions Before Submission Day — A Weekly Agent Gate for AAB/IPA Size Budgets

Mediation SDKs and bundled assets quietly inflate download size. A design for size ledgers, budget gates, and agent-driven delta attribution using bundletool and App Thinning reports.

antigravity461app-dev54android30ios38automation95

✦ Premium Article

In May 2026 I expanded the ad mediation stack in the wallpaper apps I run as an indie developer, adding Liftoff, InMobi, and Unity Ads adapters. The revenue configuration worked exactly as intended. What I only noticed after pushing an internal-test build was that the per-device download size had grown by more than 8MB. Functional tests passed. No crashes. The regression that actually mattered to users — a heavier download — sailed through every check I had, because none of my checks measured it.

Size regressions don't break builds and don't throw exceptions, so unless you measure them deliberately, they are invisible. I had gates for dependency updates and audit scripts for most other things, yet size was still on a "glance at the Play Console occasionally" basis. Since then I've given size its own budget and put an Antigravity agent on weekly watch duty. This article is the implementation record.

Where Size Quietly Grows — Three Typical Paths

Looking back over a year of size increases in my own apps, nearly all of them came from three paths.

PathTypical exampleDelta per eventHow easy to miss
Dependency additions/updatesAd adapters, analytics SDKs, UI libraries0.5–4MBHigh (lockfile diffs don't show megabytes)
Asset additionsBundled wallpapers, onboarding videos, fonts0.2–10MBMedium (the person adding them knows, but nothing records it)
Shrinker/config driftLooser R8/ProGuard keep rules, App Thinning misconfiguration1–8MBHighest (nothing was "added", yet size grew)

The third path is the nasty one. Widening a -keep rule while chasing a crash, or touching build settings, looks size-neutral in a code review. Any detection scheme based on classifying changes will eventually miss one of these. The only approach that doesn't leak is measuring the resulting number itself, every week.

Don't Measure the AAB File Size

This is the mistake I made in my first implementation: recording the size of the .aab artifact from CI. That number doesn't correspond to anything a user experiences. Play generates split APKs per device configuration from the AAB, so the actual download is much smaller than the bundle. What you want is bundletool's per-device download size.

# Get the per-device download size from an AAB
# (generate the .apks archive with build-apks first)
bundletool build-apks \
  --bundle=app/build/outputs/bundle/release/app-release.aab \
  --output=/tmp/app.apks \
  --ks=$KEYSTORE --ks-key-alias=$ALIAS \
  --ks-pass=pass:$KS_PASS --key-pass=pass:$KEY_PASS
 
# Prints MIN and MAX across device configs. Gate on MAX.
bundletool get-size total --apks=/tmp/app.apks
# Example output:
# MIN,MAX
# 21436512,24893440

I gate on MAX rather than MIN because the budget should hold even for the least favorable device configuration. On iOS, Xcode's App Thinning Size Report plays the same role: export the archive with thinning enabled and parse the largest compressed variant from App Thinning Size Report.txt.

# iOS: extract the largest thinned download size from the report
grep "compressed" "App Thinning Size Report.txt" \
  | grep -oE '[0-9.]+ MB' | sort -rn | head -1
# Example output: 31.2 MB

Both measurements must be reproducible from the command line rather than read off a store dashboard — that's the precondition for the unattended runs described below.

✦

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
✦You can put a hard numeric budget and an automated gate on the download size that creeps up with every dependency and asset addition
✦You'll learn how to build a size ledger from bundletool and App Thinning reports, and how to narrow a size delta down to the offending commit
✦You can run the whole thing as a weekly unattended check, so a size regression never surprises you on submission day
Secure payment via Stripe · Cancel anytime
✦

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $15 for lifetime access
View Membership →

Related Articles

▣ App Dev2026-04-03
Antigravity × Capacitor Hybrid App Implementation Guide: An AI-Driven Workflow for Taking a Web App to iOS/Android Native
Implementation notes for taking an existing web app to iOS/Android with Capacitor and Antigravity, drawn from running indie apps. Covers native API integration, AdMob initialization order, launch-time white flash, and pre-submission checks, separating what is verified from what is not.
▣ App Dev2026-04-19
Building a Fully Automated iOS App Release Pipeline with Antigravity — From Screenshot Generation to App Store Review Management
Use Antigravity, App Store Connect API, and GitHub Actions to automate every step from build to App Store submission. A complete advanced guide covering AI screenshot captions, metadata optimization, and rejection analysis.
▣ App Dev2026-10-08
Three Safety Nets to Test with a Fake agy Before Running the Antigravity CLI in a Container
Before you call the Antigravity CLI (agy) from Docker or a Cloud Run job, reproduce three failure modes with a fake agy: an installer that returns gzip, a hang on tool approval, and an exit code of 0 with nothing produced. Everything here rests on official docs and on code I ran myself.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links