Reduce App Size: Android & iOS Practical Guide
This guide explains how to reduce the size of a mobile app for both Android and iOS, covering the main causes of large binaries and the practical steps you can take today. You will learn concrete techniques like app bundle delivery, asset compression, and code stripping, along with how to measure the impact of each change.
Why App Size Matters
Large apps cost users storage space, take longer to download over cellular connections, and are more likely to be abandoned before installation is complete. On both platforms, there is a hard limit: the Google Play Store caps the base APK at 100 MB (though you can add up to 4 GB of additional assets), and Apple limits the app binary to 4 GB, but the recommended limit for cellular downloads is 200 MB. Beyond store limits, user behavior is clear: a 10 MB increase in download size can reduce conversion rates by roughly 1%, and many users will delete an app that consumes more than a few hundred megabytes. Reducing size is not just a technical nicety; it directly affects install rates, retention, and user satisfaction.
How App Size Is Measured
Before optimizing, you need to know what you are measuring. The size reported by the store is not the same as the size of your source code. It is the size of the compiled, packaged binary that the user downloads, which includes:
- Code – compiled native libraries (SO files on Android, Mach-O on iOS) and bytecode (DEX on Android, LLVM bitcode or native code on iOS).
- Resources – images, fonts, audio, video, and other assets bundled in the package.
- Metadata – manifest files, signing certificates, and other structural data.
On Android, the size you see in the Play Console is the size of the Android App Bundle (AAB) or APK that users download. On iOS, the size shown in App Store Connect is the size of the universal binary (or the thin binary for a specific device, depending on how you view it). Both platforms provide a breakdown of code vs. resources, so you can identify which category is dominating.
Android: Use App Bundles and Split APKs
The single most effective step for Android is to publish an Android App Bundle (AAB) instead of a monolithic APK. The bundle lets Google Play generate optimized APKs for each device configuration, so users only download the code and resources that match their screen density, CPU architecture, and language. For example, a user with an ARM64 phone and a high-density screen will not download x86 libraries or low-density images. This can reduce the download size by 30% to 50% for typical apps, sometimes more.
If you cannot switch to AAB (for example, because you sideload APKs), you can manually split your APK by ABI and density using the Android Gradle Plugin. This is more work but achieves a similar effect. Additionally, enable resource shrinking and code shrinking in your build configuration (using R8 for code and resource shrinker for unused resources). These tools remove unused code and assets, and they also obfuscate the code, which further reduces size.
iOS: Optimize Assets and Use On-Demand Resources
On iOS, the main lever is asset management. Use the Asset Catalog with the correct resolution and compression. Xcode automatically compresses PNG files using a lossless algorithm, but you can achieve better results by using the App Thinning feature, which is enabled by default when you archive for distribution. App Thinning includes:
- App Slicing – the App Store delivers only the resources needed for the user’s device (e.g., only 2x or 3x images, not both).
- Bitcode – an intermediate representation that Apple can re-optimize, though its impact on size is minor.
- On-Demand Resources (ODR) – you can mark certain assets (e.g., level packs, images, audio) as downloadable only when needed. These are hosted on Apple’s servers and are not part of the initial download.
For code, the compiler already strips dead code at the function level, but you can further reduce size by enabling the Size optimization level in Xcode (instead of Fastest), which trades a small amount of runtime performance for a smaller binary. Also, avoid embedding large static libraries; use dynamic frameworks if possible, and link only the frameworks you actually use.
Common Size Culprits and How to Fix Them
After applying the platform-level techniques, the next step is to audit your assets and libraries. The most common offenders are:
- Uncompressed images – PNG is often overkill for photos; use JPEG for photographic content and WebP on Android (which supports lossy and lossless) or HEIC on iOS. For icons and simple graphics, vector drawables on Android and PDF or SVG on iOS are much smaller.
- Multiple resolutions – If you include 1x, 2x, and 3x versions of every image, the total can be 14x the base size. Use asset catalogs to let the store slice them, and consider using a single high-resolution image with runtime resizing if the visual quality is acceptable.
- Large libraries – A single analytics or networking library can add 5–10 MB. Use the size report from your build tools to see which libraries are largest, and consider replacing heavy libraries with lighter alternatives or writing your own code for simple tasks.
- Duplicate resources – Both Android and iOS have tools to detect duplicate files (e.g., the Android resource shrinker and the iOS
ducommand on the built product). Remove any assets that appear more than once. - Unused native code – On Android, each ABI (ARM, ARM64, x86, x86_64) adds a full copy of your native libraries. If you only support ARM64 devices (which is the vast majority of modern devices), you can exclude the others in your Gradle configuration.
Measuring and Verifying Improvements
You cannot improve what you do not measure. Both platforms give you detailed size reports:
- Android – In Android Studio, use Build > Analyze APK to see a breakdown of the APK contents. The Play Console shows the download size for each device profile. You can also use the
bundletoolcommand-line tool to generate a list of APKs and their sizes. - iOS – In Xcode, the App Store Connect report shows the size for each device family. Locally, you can inspect the built app bundle in the Products folder and use the
du -shcommand to see the total size.
When you make a change, always compare the size before and after. A good practice is to set a size budget (e.g., “the app must stay under 50 MB�) and track it in CI. Also, remember that the size reported by the store may be compressed (e.g., the Play Store applies its own compression), so the actual download size is often smaller than the raw binary size.
Advanced Techniques: Code Stripping and Dynamic Delivery
For apps that are still too large, you can go further:
- Code stripping – On Android, R8 (which replaces ProGuard) removes unused classes, fields, and methods. On iOS, the linker can strip dead code at the object file level, but you must ensure that all code is reachable from the entry point. Use the
-dead_striplinker flag (enabled by default in release builds) to remove unreachable code. - Dynamic feature modules (Android) – You can split your app into modules that are downloaded on demand, similar to iOS’s ODR. For example, a game might have a “campaign� module and a “multiplayer� module, each downloaded only when the user first accesses that feature.
- Compression – On Android, you can enable
extractNativeLibs = falsein your Gradle config to store native libraries uncompressed in the APK, which reduces the download size (but increases the installed size). On iOS, the App Store already applies compression to the binary, so further compression is not effective.
One common misconception is that reducing app size always harms performance. In practice, the opposite is often true: smaller binaries load faster, use less memory, and are easier to maintain. The only trade-off is development effort and the need to test on multiple configurations.
Frequently Asked Questions
Q: Does the App Store compress my iOS app automatically?
A: Yes, Apple applies a compression algorithm to the binary and resources when you upload to App Store Connect. The size you see in the store is the compressed size, which is usually 30–50% smaller than the raw archive. You cannot control this compression, but you can minimize the raw size to get a smaller compressed size.
Q: What is the maximum allowed app size on each store?
A: The Google Play Store allows a base APK of up to 100 MB, plus up to 4 GB of additional assets using Play Asset Delivery. The Apple App Store allows a binary of up to 4 GB, but recommends a download size under 200 MB for cellular downloads. These limits are for the binary itself, not the total installed size.
Q: Will using WebP images on Android reduce size?
A: Yes, WebP is a modern image format that provides better compression than PNG or JPEG. For photos, WebP can be 25–35% smaller than JPEG at the same quality. For images with transparency, WebP is much smaller than PNG. On iOS, HEIC is the equivalent, but you can also use WebP with third-party libraries.
Q: How do I know which libraries are adding the most size?
A: On Android, use the ./gradlew assembleRelease command and then inspect the APK with Analyze APK in Android Studio to see the size of each file. On iOS, you can use the linkmap file generated by the linker to see the size of each object file. Third-party tools like size (on Linux) or du can also help.
Q: Is it safe to remove unused resources manually?
A: Yes, but it is error-prone. Use the automated resource shrinker on Android (which is part of the build process) and the asset catalog on iOS to ensure that no referenced resources are removed. If you manually delete files, you risk breaking the app if a resource is referenced dynamically (e.g., by name). Always test thoroughly after removal.
Q: Does app size affect app store search ranking?
A: Not directly. App size is not a ranking factor in either store. However, a large app may lead to lower install rates, which can indirectly affect your ranking through fewer downloads and engagement.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.